Hi,

The UpdateData function is the HTTP handler for the route which matches the 
URL and  is called after the mux.Router after receiving an incoming request 
matches the incoming request
 against the registered route. 

BR
Afriyie


On Tuesday, November 17, 2020 at 7:33:50 PM UTC+2 Afriyie Abraham Kwabena 
wrote:

> Hi,
>
> I have made changes according to the comments and also simply the main 
> function but am not sure if the worker go routine works. 
> This what i did:
>
> type Route struct {
>     Name        string
>     Method      string
>     Pattern     string
>     HandlerFunc http.HandlerFunc
> }
>
> var idtime = make(map[string]int64)
>
>
> func UpdateData(response http.ResponseWriter, request *http.Request) {
>
>     var (
>         localVarHTTPMethod = http.MethodPatch
>         patchItems         model.PatchItem
>     )
>
>     id := config.GetIdFromRequest(request)
>
>     if request.Method == localVarHTTPMethod {
>
>         err := json.NewDecoder(request.Body).Decode(&patchItems)
>         if err != nil {
>             common.WriteError(response, common.ErrBadRequest)
>             return
>         }
>
>         defer request.Body.Close()
>
>         idtime[id] = time.Now().Unix()
>
>
>         common.RespondWith3gppJsonPatchJson(response, 
> http.StatusNoContent, nil)
>     } else {
>         common.WriteError(response, common.ErrMethodNotAllowed)
>         return
>     }
> }
>
> var (
>     mu  sync.Mutex
>     ctx = context.Background()
> )
>
> func worker() {
>     mu.Lock()
>     for keyid := range idtime {
>
>         d := time.Now().Unix() - idtime[keyid]
>         if d >= 60 {
>
>             // delete resouce in database after 60 seconds
>             _ = DeleteNFInstance(ctx, keyid)
>         }
>     }
>     mu.Unlock()
> }
>
> // Delete info
> func DeleteNFInstance(ctx context.Context, nfinstanceId string) bool {
>     filter := bson.M{"_id": nfinstanceId}
>     _, err := db.Collection(COLLECTION).DeleteOne(ctx, filter)
>     if err != nil {
>         return false
>     }
>     return true
> }
>
> type Routes []Route
>
> func NewRouter() *mux.Router {
>     router := mux.NewRouter().StrictSlash(true)
>     for _, route := range routes {
>         var handler http.Handler
>         handler = route.HandlerFunc
>
>         router.
>             Methods(route.Method).
>             Path(route.Pattern).
>             Name(route.Name).
>             Handler(handler)
>     }
>
>     return router
> }
>
> var routes = Routes{
>
>     Route{
>         "UpdateData",
>         strings.ToUpper("Patch"),
>         "/users/{id}",
>         UpdateData,
>     },
> }
>
> // main function
> func main() {
>     r := NewRouter()
>
>     go worker()
>
>
>     fmt.Println("Start listening")
>     fmt.Println(http.ListenAndServe(":8080", r))
> }
>
> I appreciate your help but am still not able to it work.
>
>
> On Tuesday, November 17, 2020 at 3:48:44 PM UTC+2 Shulhan wrote:
>
>> Hi Afriyie, 
>>
>> Looks like you almost there ;) 
>>
>> > On 17 Nov 2020, at 20.11, Afriyie Abraham Kwabena <afriyie...@gmail.com> 
>> wrote: 
>> > 
>> > HI, 
>> > 
>> > This is what I have tried so far but am not able to get the time 
>> difference in seconds. I mean the time differences between the time stored 
>> in the map[string]time.Time and 
>> > the current time in seconds. 
>> > 
>> > code: 
>> > 
>> > type Server struct { 
>> > idtime map[string]time.Time 
>> > } 
>> > 
>> > var my = Server{} 
>> > 
>> > func main() { 
>> > r := mux.NewRouter() 
>> > usersData := r.PathPrefix("/users").Subrouter() 
>> > 
>> usersData.Path("/{id}").Methods(http.MethodPatch).HandlerFunc(UpdateData) 
>> > 
>>
>> Based on my understanding (I have never use mux before), the UpdateDate 
>> function will be running concurrently as goroutine. Lets say that we have 
>> three PATCH requests at the same time, there will be three UpdateData 
>> running concurrently or in parallel. 
>>
>> > fmt.Println("Start listening") 
>> > fmt.Println(http.ListenAndServe(":8080", r)) 
>> > } 
>> > 
>> > func UpdateData(response http.ResponseWriter, request *http.Request) { 
>> > 
>> > var ( 
>> > localVarHTTPMethod = http.MethodPatch 
>> > patchItems model.PatchItem 
>> > ) 
>> > 
>> > id := config.GetIdFromRequest(request) 
>> > 
>> > if request.Method == localVarHTTPMethod { 
>> > 
>> > err := json.NewDecoder(request.Body).Decode(&patchItems) 
>> > if err != nil { 
>> > common.WriteError(response, common.ErrBadRequest) 
>> > return 
>> > } 
>> > 
>> > defer request.Body.Close() 
>> > 
>> > my.idtime = make(map[string]time.Time) 
>>
>> Since the UpdateData is running independently for each request, you 
>> should initialize this once, in the main, otherwise each UpdateData routine 
>> will reset the idtime variable. 
>>
>> > my.idtime[id] = time.Now() 
>> > 
>> > go func() { 
>> > for keyid, t := range my.idtime { 
>> > 
>> > ts := t.Format(time.RFC3339) 
>> > 
>> > v, err := time.Parse(time.RFC3339, ts) 
>> > if err != nil { 
>> > fmt.Println(err) 
>> > os.Exit(1) 
>> > } 
>> > 
>> > timeRemaining := getTimeRemaining(v) 
>> > 
>> > if timeRemaining.S >= 60 { 
>> > // delete resouce in database after 60 seconds 
>> > deleteResourceUsingIdkey(keyid) 
>> > } 
>> > } 
>> > }() 
>>
>> Also, you should move the above goroutine to main, otherwise each call to 
>> UpdateData will spawn a new goroutine. 
>>
>> If I were you I will use the Unix time [1] instead of Time object, its 
>> much simpler `time.Now().Unix() - my.idtime[keyid] >= 60`. 
>>
>> BTW, beware of race condition. Test or build your program with "-race" 
>> option to see it by yourself. Use sync.Mutex [2] to prevent the write 
>> (updating the map) overlap with read (checking the elapsed seconds). 
>>
>> [1] https://pkg.go.dev/time#Time.Unix 
>> [2] https://pkg.go.dev/sync#Mutex 
>>
>> > 
>> > common.RespondWith3gppJsonPatchJson(response, http.StatusNoContent, 
>> nil) 
>> > } else { 
>> > 
>> > common.WriteError(response, common.ErrMethodNotAllowed) 
>> > return 
>> > } 
>>
>> Another things that I can't not comment, you can simplify the code by 
>> returning-first, which minimize code identation. 
>>
>> > } 
>> > 
>> > type count struct { 
>> > S int 
>> > } 
>> > 
>> > func getTimeRemaining(t time.Time) count { 
>> > currentTime := time.Now() 
>> > difference := t.Sub(currentTime) 
>> > 
>> > seconds := int(difference.Seconds()) 
>> > 
>> > return count{ 
>> > S: seconds, 
>> > } 
>> > } 
>> > 
>> > func deleteResourceUsingIdkey(idkey string) { 
>> > // do delete here 
>> > } 
>> > 
>> > Any help. 
>> > 
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/0d856e1a-2d5b-40ab-a45f-33acb2b7edean%40googlegroups.com.

Reply via email to