Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-27 Thread b.ca...@pobox.com
I should add: using channels often means the mutex is not required.

Imagine, for example, that you want a concurrency-safe counter (that 
multiple goroutines can read, increment and decrement).  You can put the 
counter value into a buffered channel:

counter := make(chan int, 1)
counter <- 0

Then you pull the value out of channel while you're working on it, and put 
it back when you're finished.

// Read counter
cv := <- counter
fmt.Println("Counter is %d", cv)
counter <- cv

// Increment counter
counter <- (<-counter + 1)

This is all safe because only one goroutine has possession of the counter 
value at any time.  Just make sure you always put it back (it can be 
helpful to write functions to do the accessing, and use 'defer' to put the 
value back)

-- 
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/c6de9b79-857c-41fd-bcb2-f62f1ddd7e71n%40googlegroups.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-27 Thread Afriyie Abraham Kwabena
Hi,

THanks!!

BR
Abraham

On Friday, November 27, 2020 at 11:12:53 AM UTC+2 b.ca...@pobox.com wrote:

> On Friday, 27 November 2020 at 06:14:48 UTC Afriyie Abraham Kwabena wrote:
>
>> What I would like to ask is, using mutex OK and if not the best way of 
>> solving it, how can i use
>> channels in this case.
>>
>
> There's nothing wrong with mutex, but you can use channels for a more 
> native-Go experience.
> This video is well worth watching: 
> https://www.youtube.com/watch?v=5zXAHh5tJqQ
>
> In short, you can get mutex or semaphore-like behaviour by having a 
> channel with fixed depth, and putting/pulling values from it.
> Playground 
>
> mutex := make(chan struct{}, 1)
> ...
>
> mutex <- struct{}{}
> ... do stuff
> <-mutex
>
>

-- 
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/e59c6a22-030c-479a-ba8a-b61948307b62n%40googlegroups.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-27 Thread b.ca...@pobox.com
On Friday, 27 November 2020 at 06:14:48 UTC Afriyie Abraham Kwabena wrote:

> What I would like to ask is, using mutex OK and if not the best way of 
> solving it, how can i use
> channels in this case.
>

There's nothing wrong with mutex, but you can use channels for a more 
native-Go experience.
This video is well worth 
watching: https://www.youtube.com/watch?v=5zXAHh5tJqQ

In short, you can get mutex or semaphore-like behaviour by having a channel 
with fixed depth, and putting/pulling values from it.
Playground 

mutex := make(chan struct{}, 1)
...

mutex <- struct{}{}
... do stuff
<-mutex

-- 
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/a3c1e84d-5d68-4862-a94a-9180ae943485n%40googlegroups.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-26 Thread Afriyie Abraham Kwabena
Hi,

I just produce the warning for clarity. sorry for the huge message 


==
WARNING: DATA RACE
Write at 0x00c0002d6480 by goroutine 48:
  runtime.mapdelete_faststr()
  /usr/local/go/src/runtime/map_faststr.go:297 +0x0
  nfnrfapi/services/manag.UpdateNFInstance()
  
/home/xxx/go/src/nfnrfapi/services/manag/api_nf_instance_id_document_Update.go:48
 
+0x46d
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  nfnrfapi/common.RecoverHandler.func1()
  /home/xxx/go/src/nfnrfapi/common/middlewares.go:56 +0xe6
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  github.com/NYTimes/gziphandler.GzipHandlerWithOpts.func1.1()
  
/home/xxx/go/pkg/mod/github.com/!n!y!times/gziphandler@v1.1.1/gzip.go:336 
+0x45e
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  github.com/gorilla/mux.(*Router).ServeHTTP()
  /home/xxx/go/pkg/mod/github.com/gorilla/mux@v1.8.0/mux.go:210 +0x132
  nfnrfapi/common.Logging.func1.1()
  /home/xxx/go/src/nfnrfapi/common/middlewares.go:42 +0xcf
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  nfnrfapi/common.Tracing.func1.1()
  /home/xxx/go/src/nfnrfapi/common/middlewares.go:26 +0x454
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  net/http.serverHandler.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2843 +0xca
  net/http.initALPNRequest.ServeHTTP()
  /usr/local/go/src/net/http/server.go:3415 +0x104
  net/http.(*initALPNRequest).ServeHTTP()
  :1 +0xa6
  net/http.Handler.ServeHTTP-fm()
  /usr/local/go/src/net/http/server.go:87 +0x64
  golang.org/x/net/http2.(*serverConn).runHandler()
  
/home/xxx/go/pkg/mod/golang.org/x/net@v0.0.0-20201031054903-ff519b6c9102/http2/server.go:2152
 
+0xc5

Previous read at 0x00c0002d6480 by goroutine 18:
  runtime.mapiterinit()
  /usr/local/go/src/runtime/map.go:797 +0x0
  nfnrfapi/services/manag.PollingWorker()
  
/home/xxx/go/src/nfnrfapi/services/manag/api_nf_instance_id_document_Update.go:111
 
+0x604

Goroutine 48 (running) created at:
  golang.org/x/net/http2.(*serverConn).processHeaders()
  
/home/xxx/go/pkg/mod/golang.org/x/net@v0.0.0-20201031054903-ff519b6c9102/http2/server.go:1882
 
+0x924
  golang.org/x/net/http2.(*serverConn).processFrame()
  
/home/xxx/go/pkg/mod/golang.org/x/net@v0.0.0-20201031054903-ff519b6c9102/http2/server.go:1410
 
+0x41e
  golang.org/x/net/http2.(*serverConn).processFrameFromReader()
  
/home/xxx/go/pkg/mod/golang.org/x/net@v0.0.0-20201031054903-ff519b6c9102/http2/server.go:1368
 
+0x7d9
  golang.org/x/net/http2.(*serverConn).serve()
  
/home/xxx/go/pkg/mod/golang.org/x/net@v0.0.0-20201031054903-ff519b6c9102/http2/server.go:869
 
+0x14fc
  golang.org/x/net/http2.(*Server).ServeConn()
  
/home/xxx/go/pkg/mod/golang.org/x/net@v0.0.0-20201031054903-ff519b6c9102/http2/server.go:472
 
+0xdc4
  golang.org/x/net/http2.ConfigureServer.func1()
  
/home/xxx/go/pkg/mod/golang.org/x/net@v0.0.0-20201031054903-ff519b6c9102/http2/server.go:298
 
+0x11e
  net/http.(*conn).serve()
  /usr/local/go/src/net/http/server.go:1834 +0x1d5b

Goroutine 18 (running) created at:
  main.main()
  /home/xxx/go/src/nfnrfapi/main.go:41 +0x2c6
==
==
WARNING: DATA RACE
Write at 0x00cf7a88 by goroutine 48:
  nfnrfapi/services/manag.UpdateNFInstance()
  
/home/xxx/go/src/nfnrfapi/services/manag/api_nf_instance_id_document_Update.go:50
 
+0x53c
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  nfnrfapi/common.RecoverHandler.func1()
  /home/xxx/go/src/nfnrfapi/common/middlewares.go:56 +0xe6
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  github.com/NYTimes/gziphandler.GzipHandlerWithOpts.func1.1()
  
/home/xxx/go/pkg/mod/github.com/!n!y!times/gziphandler@v1.1.1/gzip.go:336 
+0x45e
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  github.com/gorilla/mux.(*Router).ServeHTTP()
  /home/xxx/go/pkg/mod/github.com/gorilla/mux@v1.8.0/mux.go:210 +0x132
  nfnrfapi/common.Logging.func1.1()
  /home/xxx/go/src/nfnrfapi/common/middlewares.go:42 +0xcf
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  nfnrfapi/common.Tracing.func1.1()
  /home/xxx/go/src/nfnrfapi/common/middlewares.go:26 +0x454
  net/http.HandlerFunc.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2042 +0x51
  net/http.serverHandler.ServeHTTP()
  /usr/local/go/src/net/http/server.go:2843 +0xca
  net/http.initALPNRequest.ServeHTTP()
  /usr/local/go/src/net/http/server.go:3415 +0x104
  net/http.(*initALPNRequest).ServeHTTP()
  :1 +0xa6
  net/http.Handler.ServeHTTP-fm()
  /usr/local/go/src/net/http/server.go:87 +0x64
  golang.org/x/net/http2.(*serverConn).runHandler()
 

Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-26 Thread Afriyie Abraham Kwabena
Hi,

Yes from the warning it prints the handler function below and after google 
searching what i did was to mutex.Lock and Unlock the handler function and 
no warning again.
However, my google search people mention of using channels instead of 
mutex. What I would like to ask is, using mutex OK and if not the best way 
of solving it, how can i use
channels in this case.

Handler function below:

func UpdateNFInstance(response http.ResponseWriter, request *http.Request) {

mu.Lock()
defer mu.Unlock()

var (
localVarHTTPMethod = http.MethodPatch
ctx= context.Background()
patchItems model.PatchItem
)

id := config.GetIdFromRequest(request)

if request.Method == localVarHTTPMethod {

if request.Header.Get("Content-Type") != 
"application/json-patch+json" {
common.WriteError(response, 
common.ErrStatusUnsupportedMediaTypePatch)
return
}

err := json.NewDecoder(request.Body).Decode()
if err != nil {
common.WriteError(response, common.ErrBadRequest)
return
}

defer request.Body.Close()

delete(idtime, id) // delete value in map if exit

idtime[id] = time.Now().Unix()

nfProfile, err := config.Conf.FindNFInstanceProfileById(ctx, id)
if err != nil {
common.WriteError(response, common.ErrNotFound)
return
}

if patchItems.Path == "/nfStatus" {

nfProfile.NfStatus = patchItems.Value
nfProfile.LoadTimeStamp = time.Now().String()

success := config.Conf.UpdateNFInstanceHeartBeatNfStatus(ctx, 
nfProfile, id)
if !success {
common.WriteError(response, common.ErrInternalServer)
return
}

if request.URL.Scheme != "" {
scheme = request.URL.Scheme
}
response.Header().Set("Content-Location", 
scheme+"://"+request.Host+request.URL.Path)
response.Header().Set("Response-Desc", "Success")
common.RespondWith3gppJSONPatchJSON(response, 
http.StatusNoContent, nil)

} else {
// patchItems.Path == "/load" information
v, err := strconv.Atoi(patchItems.Value)
if err != nil {
config.Logrus.Errorf("Failed to convert Patch Item Value 
string to integer: %s", err.Error())
}

nfProfile.Load = int32(v)
nfProfile.LoadTimeStamp = time.Now().String()

success := config.Conf.UpdateNFInstanceHeartBeatLoad(ctx, 
nfProfile, id)
if !success {
common.WriteError(response, common.ErrInternalServer)
return
}

if request.URL.Scheme != "" {
scheme = request.URL.Scheme
}
response.Header().Set("Content-Location", 
scheme+"://"+request.Host+request.URL.Path)
response.Header().Set("Response-Desc", "Success")
common.RespondWith3gppJSONPatchJSON(response, 
http.StatusNoContent, nil)

}
} else {
common.WriteError(response, common.ErrMethodNotAllowed)
return
}
}


BR
Abraham

On Friday, November 27, 2020 at 6:38:52 AM UTC+2 Shulhan wrote:

>
>
> > On 27 Nov 2020, at 07.06, Afriyie Abraham Kwabena  
> wrote:
> > 
> > Hi,
> > 
> > Am experiencing data race warning with my pollingworker function below 
> even though when i build with the -race flag i do not get any error. Any 
> help?
> > 
>
> Usually when you got data race warning it will print the line that cause 
> read and write race condition. Pay attention to both lines and I think you 
> will find the cause.
>
> It's kind of hard to figure it out only through a single function. It 
> could be in config.Conf or in function that manipulate idtime outside the 
> pollingworker.
>
>

-- 
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/9fae8852-b60d-4c76-9939-b997db3d685cn%40googlegroups.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-26 Thread Shulhan



> On 27 Nov 2020, at 07.06, Afriyie Abraham Kwabena  
> wrote:
> 
> Hi,
> 
> Am experiencing data race warning with my pollingworker function below even 
> though when i build with the  -race flag i do not get any error. Any help?
> 

Usually when you got data race warning it will print the line that cause read 
and write race condition. Pay attention to both lines and I think you will find 
the cause.

It's kind of hard to figure it out only through a single function. It could be 
in config.Conf or in function that manipulate idtime outside the pollingworker.

-- 
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/E114D8FD-9EC8-49B3-A7B0-866BA87023EA%40gmail.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-26 Thread Afriyie Abraham Kwabena
Hi,

Am experiancing data race warning with my pollingworker function below even 
though when i build with the  -race flag i do not get any error. Any help?

func PollingWorker() {
tiker := time.NewTicker(60 * time.Second)
for _ = range tiker.C {
mu.Lock()
for keyid := range idtime {
d := time.Now().Unix() - idtime[keyid]
if d >= 60 {
// Find nfinstance using keyid
nfinstanceProfile, err := 
config.Conf.FindNFInstanceProfileById(ctx, keyid)
if err != nil {
config.Logrus.Error("Could not find NF Instance Profile 
with ID :" + keyid + " to SUSPEND Status")
}
// change nfStatus of nfinstance to SUSPENDED
err = config.Conf.SuspendNFInstanceNfStatus(ctx, 
nfinstanceProfile, keyid)
if err != nil {
config.Logrus.Error(err)
}
delete(idtime, keyid)
}
}
mu.Unlock()
}
}


BR
Abraham
On Wednesday, November 18, 2020 at 10:51:49 AM UTC+2 Afriyie Abraham 
Kwabena wrote:

> Hi Sulhan,  Anderson,
>
> Thanks for your guidance. It works now using time.Ticker
>
> func worker() {
> tiker := time.NewTicker(30 * time.Second)
> for _ = range tiker.C {
>
> 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()
> }
> }
>
> BR
> Abraham
>
>
>
> On Tuesday, November 17, 2020 at 9:41:01 PM UTC+2 Shulhan wrote:
>
>>
>>
>> > On 18 Nov 2020, at 01.06, Afriyie Abraham Kwabena  
>> wrote: 
>> > 
>> > 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. 
>>
>> ... 
>>
>> > 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() 
>> > if err != nil { 
>> > common.WriteError(response, common.ErrBadRequest) 
>> > return 
>> > } 
>> > 
>> > defer request.Body.Close() 
>> > 
>> > idtime[id] = time.Now().Unix() 
>> > 
>>
>> We still may have data race here. 
>>
>> > 
>> > 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() 
>> > } 
>> > 
>>
>> ... 
>>
>> > // 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. 
>> > 
>>
>> Looks like your worker only loop once and then it finished. Either you 
>> use time.Sleep() to repeat the loop inside loop or use time.Ticker [1]. 
>>
>> [1] https://pkg.go.dev/time#Ticker 
>>
>>

-- 
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/9db5a074-0b0a-4f3a-ab20-7c5d67f458a0n%40googlegroups.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-18 Thread Afriyie Abraham Kwabena
Hi Sulhan,  Anderson,

Thanks for your guidance. It works now using time.Ticker

func worker() {
tiker := time.NewTicker(30 * time.Second)
for _ = range tiker.C {
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()
}
}

BR
Abraham



On Tuesday, November 17, 2020 at 9:41:01 PM UTC+2 Shulhan wrote:

>
>
> > On 18 Nov 2020, at 01.06, Afriyie Abraham Kwabena  
> wrote:
> > 
> > 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. 
>
> ...
>
> > 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()
> > if err != nil {
> > common.WriteError(response, common.ErrBadRequest)
> > return
> > }
> > 
> > defer request.Body.Close()
> > 
> > idtime[id] = time.Now().Unix()
> > 
>
> We still may have data race here.
>
> > 
> > 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()
> > }
> > 
>
> ...
>
> > // 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.
> > 
>
> Looks like your worker only loop once and then it finished. Either you use 
> time.Sleep() to repeat the loop inside loop or use time.Ticker [1].
>
> [1] https://pkg.go.dev/time#Ticker
>
>

-- 
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/cc7b885f-074a-4b23-9f4c-08d4a3a7ac62n%40googlegroups.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-17 Thread Shulhan



> On 18 Nov 2020, at 01.06, Afriyie Abraham Kwabena  
> wrote:
> 
> 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. 

...

> 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()
> if err != nil {
> common.WriteError(response, common.ErrBadRequest)
> return
> }
> 
> defer request.Body.Close()
> 
> idtime[id] = time.Now().Unix()
> 

We still may have data race here.

> 
> 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()
> }
> 

...

> // 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.
> 

Looks like your worker only loop once and then it finished.  Either you use 
time.Sleep() to repeat the loop inside loop or use time.Ticker [1].

[1] https://pkg.go.dev/time#Ticker

-- 
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/B0663F2A-D51D-43D5-8D63-95C73B51DF90%40gmail.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-17 Thread Afriyie Abraham Kwabena
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 {
> Namestring
> 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()
> 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  
>> 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() 
>> > 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) 
>> > } 
>> > 
>> > 

Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-17 Thread Afriyie Abraham Kwabena
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 {
Namestring
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()
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  
> 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()
> > 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).
>
> 

Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-17 Thread Shulhan
Hi Afriyie,

Looks like you almost there ;)

> On 17 Nov 2020, at 20.11, Afriyie Abraham Kwabena  
> 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()
> 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/3F1FDD40-AD43-413C-BE21-0BE7EB327F32%40gmail.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-17 Thread Afriyie Abraham Kwabena
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)

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()
if err != nil {
common.WriteError(response, common.ErrBadRequest)
return
}

defer request.Body.Close()

my.idtime = make(map[string]time.Time)
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)
}
}
}()

common.RespondWith3gppJsonPatchJson(response, http.StatusNoContent, 
nil)
} else {

common.WriteError(response, common.ErrMethodNotAllowed)
return
}
}

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.


On Tuesday, November 17, 2020 at 10:34:39 AM UTC+2 Anderson Queiroz wrote:

> Just one thing to keep in mind. Likely you have more than one serve 
> instance running to process the requests. Thus it might happen the client 
> will poll a different server on every request. Just imagine you have 
> servers A, B, C behind a load balance and the domain example.com. As the 
> client is pooling example.com, the first request might reach A, the 
> second B and the third C. Now you have the 3 servers tracking the same 
> client. It might happen server A doesn't receive any request from the 
> client for a while, but not because the client isn't pooling any more, but 
> because all requests are being directed to either B or C.
>
> On Tuesday, 17 November 2020 at 07:12:18 UTC+1 Shulhan wrote:
>
>>
>>
>> > On 16 Nov 2020, at 16.24, Afriyie Abraham Kwabena  
>> wrote: 
>> > 
>> > Hi , 
>> > 
>> > You are right but am new to programming and currently this what i have 
>> done. 
>> > I have an http server handler that receives the PATCH request and 
>> stores the id and the current time stamp of the request. 
>> > But my problem is how to write the worker function to do the clean up 
>> every X seconds. 
>> > 
>> > Code: 
>> > 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() 
>> > if err != nil { 
>> > common.WriteError(response, common.ErrBadRequest) 
>> > return 
>> > } 
>> > 
>> > defer request.Body.Close() 
>> > 
>> > var idtime = make(map[string]string) 
>> > 
>> > delete(idtime, id) // delete if already exist 
>> > idtime[id] = time.Now() // store id and time stamp in map 
>>
>> You should store idtime inside the server/service type (the one that have 
>> HTTP handlers). For example, 
>>
>>  
>> type Server struct { 
>> idtime map[string]string 
>> } 
>>
>> func (my *Server) UpdateData(...) { 
>> ... 
>> my.idtime[id] = time.Now() 
>> ... 
>> } 
>>  
>>
>> > 
>> > // how do i write a worker to the clean up after every X seconds? 
>> > 
>>
>> Create a function that loop forever and loop the map to check the time, 
>> then run the function using goroutine before you start your HTTP server. 
>>
>> > } else { 
>> > common.WriteError(response, common.ErrMethodNotAllowed) 
>> > return 
>> > } 
>> > } 
>> > 
>>
>>
>>
>>

-- 
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 

Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-17 Thread Anderson Queiroz
Just one thing to keep in mind. Likely you have more than one serve 
instance running to process the requests. Thus it might happen the client 
will poll a different server on every request. Just imagine you have 
servers A, B, C behind a load balance and the domain example.com. As the 
client is pooling example.com, the first request might reach A, the second 
B and the third C. Now you have the 3 servers tracking the same client. It 
might happen server A doesn't receive any request from the client for a 
while, but not because the client isn't pooling any more, but because all 
requests are being directed to either B or C.

On Tuesday, 17 November 2020 at 07:12:18 UTC+1 Shulhan wrote:

>
>
> > On 16 Nov 2020, at 16.24, Afriyie Abraham Kwabena  
> wrote:
> > 
> > Hi ,
> > 
> > You are right but am new to programming and currently this what i have 
> done.
> > I have an http server handler that receives the PATCH request and stores 
> the id and the current time stamp of the request.
> > But my problem is how to write the worker function to do the clean up 
> every X seconds.
> > 
> > Code:
> > 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()
> > if err != nil {
> > common.WriteError(response, common.ErrBadRequest)
> > return
> > }
> > 
> > defer request.Body.Close()
> > 
> > var idtime = make(map[string]string)
> > 
> > delete(idtime, id) // delete if already exist 
> > idtime[id] = time.Now() // store id and time stamp in map 
>
> You should store idtime inside the server/service type (the one that have 
> HTTP handlers). For example,
>
> 
> type Server struct {
> idtime map[string]string
> }
>
> func (my *Server) UpdateData(...) {
> ...
> my.idtime[id] = time.Now()
> ...
> }
> 
>
> > 
> > // how do i write a worker to the clean up after every X seconds? 
> > 
>
> Create a function that loop forever and loop the map to check the time, 
> then run the function using goroutine before you start your HTTP server.
>
> > } else {
> > common.WriteError(response, common.ErrMethodNotAllowed)
> > return
> > }
> > }
> > 
>
>
>
>

-- 
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/75e53871-6821-4ef6-8eb5-a7cb9062fb53n%40googlegroups.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-16 Thread Shulhan



> On 16 Nov 2020, at 16.24, Afriyie Abraham Kwabena  
> wrote:
> 
> Hi ,
> 
> You are right but am new to programming and currently this what i have done.
> I have an http server handler that receives the PATCH request and stores the 
> id and the current time stamp of the request.
> But my problem is how to write the worker function to do the clean up every X 
> seconds.
> 
> Code:
> 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()
> if err != nil {
> common.WriteError(response, common.ErrBadRequest)
> return
> }
> 
> defer request.Body.Close()
> 
> var idtime = make(map[string]string)
> 
> delete(idtime, id) // delete if already exist 
> idtime[id] = time.Now() // store id and time stamp in map 

You should store idtime inside the server/service type (the one that have HTTP 
handlers). For example,


type Server struct {
  idtime map[string]string
}

func (my *Server) UpdateData(...) {
...
my.idtime[id] = time.Now()
...
}


> 
> // how do i write a worker to the clean up after every X seconds? 
> 

Create a function that loop forever and loop the map to check the time, then 
run the function using goroutine before you start your HTTP server.

> } else {
> common.WriteError(response, common.ErrMethodNotAllowed)
> return
> }
> }
> 



-- 
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/906DFB35-7264-47B0-9E28-42E50694D8B1%40gmail.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-16 Thread Afriyie Abraham Kwabena
Hi ,

You are right but am new to programming and currently this what i have done.
I have an http server handler that receives the PATCH request and stores 
the id and the current time stamp of the request.
But my problem is how to write the worker function to do the clean up every 
X seconds.

Code:
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()
if err != nil {
common.WriteError(response, common.ErrBadRequest)
return
}

defer request.Body.Close()

var idtime = make(map[string]string)

delete(idtime, id) // delete if already exist 
idtime[id] = time.Now() // store id and time stamp in map 

// how do i write a worker to the clean up after every X seconds? 

} else {
common.WriteError(response, common.ErrMethodNotAllowed)
return
}
}

BR
Abraham



On Sunday, November 15, 2020 at 9:01:27 AM UTC+2 Shulhan wrote:

>
> > On 14 Nov 2020, at 20.06, Afriyie Abraham Kwabena  
> wrote:
> > 
> > Hi,
> > 
> > My question is about multiple HTTP client polling an HTTP server 
> randomly with a PATCH request to update a resource at the server running in 
> front of MongoDB. The clients poll with their different ids and a valid 
> time in their request. At the server, I can keep their ids and their 
> different times. 
> > How can detect at the server if a specific client stop polling. I would 
> like to write a function that detect at the HTTP server if a specific 
> client stop polling and then remove its resources after some time from a 
> database. Am using gorilla/mux package for the server. Any help, am new to 
> Golang programming. 
> > 
>
> I think this is not Go specific, but more like engineering in general.
>
> My suggestion is you can store the last time when user request to PATCH 
> endpoint in some storage or internal memory (like map[userID]timestamp) and 
> then have some worker that check the timestamp to clean it up every X 
> seconds or minutes.

-- 
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/7798fe2c-d176-4514-8fe0-04b6e19f4399n%40googlegroups.com.


Re: [go-nuts] How to detect HTTP client stop polling at the server side

2020-11-14 Thread Shulhan


> On 14 Nov 2020, at 20.06, Afriyie Abraham Kwabena  
> wrote:
> 
> Hi,
> 
> My  question is  about multiple HTTP client polling an HTTP server randomly 
> with a PATCH request to update a resource at the server running in front of 
> MongoDB. The clients poll with their different ids and a valid time in their 
> request. At the server, I can keep their ids and their different times. 
> How can detect at the server if a specific client stop polling. I would like 
> to write a function that detect at the HTTP server if a specific client stop 
> polling and then remove its resources after some time from a database.  Am 
> using gorilla/mux package for the server. Any  help, am new to Golang 
> programming. 
> 

I think this is not Go specific, but more like engineering in general.

My suggestion is you can store the last time when user request to PATCH 
endpoint in some storage or internal memory (like map[userID]timestamp) and 
then have some worker that check the timestamp to clean it up every X seconds 
or minutes.

-- 
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/EA52034E-DFED-4853-8720-402BF5E8967F%40gmail.com.


[go-nuts] How to detect HTTP client stop polling at the server side

2020-11-14 Thread Afriyie Abraham Kwabena
Hi,

My  question is  about multiple HTTP client polling an HTTP server randomly 
with a PATCH request to update a resource at the server running in front of 
MongoDB. The clients poll with their different ids and a valid time in 
their request. At the server, I can keep their ids and their different 
times. 
How can detect at the server if a specific client stop polling. I would 
like to write a function that detect at the HTTP server if a specific 
client stop polling and then remove its resources after some time from a 
database.  Am using gorilla/mux package for the server. Any  help, am new 
to Golang programming. 

Thanks in advance

-- 
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/8658410c-5cac-4dff-80e3-ebb1b8bbb5een%40googlegroups.com.