Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop tequila after current request is finished, instead of delay #219

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/commands/client/command_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func NewCommandWith(
tequilapi_endpoints.AddRoutesForIdentities(router, identityManager, mysteriumClient, signerFactory)
tequilapi_endpoints.AddRoutesForConnection(router, connectionManager, ipResolver, statsKeeper)
tequilapi_endpoints.AddRoutesForProposals(router, mysteriumClient)
tequilapi_endpoints.AddRouteForStop(router, node_cmd.NewApplicationStopper(command.Kill), time.Second)
tequilapi_endpoints.AddRouteForStop(router, node_cmd.NewApplicationStopper(command.Kill))

return command
}
Expand Down
23 changes: 10 additions & 13 deletions tequilapi/endpoints/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,25 @@ import (
log "github.com/cihub/seelog"
"github.com/julienschmidt/httprouter"
"net/http"
"time"
)

// ApplicationStopper stops application and performs required cleanup tasks
type ApplicationStopper func()

// AddRouteForStop adds stop route to given router
func AddRouteForStop(router *httprouter.Router, stop ApplicationStopper, delay time.Duration) {
router.POST("/stop", newStopHandler(stop, delay))
func AddRouteForStop(router *httprouter.Router, stop ApplicationStopper) {
router.POST("/stop", newStopHandler(stop))
}

func newStopHandler(stop ApplicationStopper, delay time.Duration) httprouter.Handle {
return func(response http.ResponseWriter, _ *http.Request, _ httprouter.Params) {
log.Info("Client is stopping")
delayExecution(stop, delay)
func newStopHandler(stop ApplicationStopper) httprouter.Handle {
return func(response http.ResponseWriter, req *http.Request, _ httprouter.Params) {
log.Info("Application stop requested")

go callStopWhenNotified(req.Context().Done(), stop)
response.WriteHeader(http.StatusAccepted)
}
}

func delayExecution(function func(), duration time.Duration) {
go func() {
time.Sleep(duration)
function()
}()
func callStopWhenNotified(notify <-chan struct{}, stopApplication ApplicationStopper) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not simply stopWhenNotified?

<-notify
stopApplication()
}
12 changes: 8 additions & 4 deletions tequilapi/endpoints/stop_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package endpoints

import (
"context"
"github.com/julienschmidt/httprouter"
"github.com/stretchr/testify/assert"
"net/http"
Expand All @@ -26,19 +27,22 @@ func (fs *fakeStopper) Stop() {

func TestAddRouteForStop(t *testing.T) {
stopper := fakeStopper{
stopAllowed: make(chan struct{}),
stopped: make(chan struct{}),
stopAllowed: make(chan struct{}, 1),
stopped: make(chan struct{}, 1),
}
router := httprouter.New()
AddRouteForStop(router, stopper.Stop, 0)
AddRouteForStop(router, stopper.Stop)

resp := httptest.NewRecorder()
req := httptest.NewRequest("POST", "/stop", strings.NewReader(""))

cancelCtx, finishRequestHandling := context.WithCancel(context.Background())
req := httptest.NewRequest("POST", "/stop", strings.NewReader("")).WithContext(cancelCtx)
router.ServeHTTP(resp, req)
assert.Equal(t, http.StatusAccepted, resp.Code)
assert.Equal(t, 0, len(stopper.stopped))

stopper.AllowStop()
finishRequestHandling()

select {
case <-stopper.stopped:
Expand Down