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/eff359bb-72e2-4f8b-a265-68f395553021n%40googlegroups.com.