Pattern for handling HTTP requests via channels











up vote
0
down vote

favorite












I am writing a web application where I have a long running goroutine.
I want to delegate all HTTP requests to this goroutine via channels.
The pattern that I have come across is:



// Internal long running goroutine
for{
select{
case e := <-event: //web request
req := e.req
// do something
....
select {
case <-ctx.Done():
//log
default:
e.replyTo <- result
}
}
}

// Web handler
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
//decode request etc
...

replyTo := make(chan interface{}, 1)
ctx, cancel := context.WithCancel(context.BackGround())
event <- Event{req: req, ctx: ctx, replyTo: replyTo}
select{
case <-time.After(time.Second):
cancel()
//return 500
case r := <-replyTo:
// return some response
}
})


I do see that there is one single go-routine at the end, so parallelism is lost but I am okay with it.



Is this pattern the right way of doing this?
What other approaches can be suggested?










share|improve this question
























  • What are you trying to accomplish? Why not just use net/http?
    – Flimzy
    Nov 18 at 8:48










  • I am using net/http... the handler function is delegating the work to goroutine which has data
    – Saurav Prakash
    Nov 18 at 8:49










  • "Is this pattern the right way of doing this?" -- the right way of doing what? You still haven't explained your goal. Why go to all this effort to seemingly undermine the standard library, and make your code less efficient?
    – Flimzy
    Nov 18 at 8:53








  • 1




    The handler function doesnt have enough state to handle request..It delegates it to another goroutine which has the required data procured from some other place. is that what you are trying to achieve?
    – Shank
    Nov 18 at 8:55












  • @Shank Yes exactly
    – Saurav Prakash
    Nov 18 at 8:57















up vote
0
down vote

favorite












I am writing a web application where I have a long running goroutine.
I want to delegate all HTTP requests to this goroutine via channels.
The pattern that I have come across is:



// Internal long running goroutine
for{
select{
case e := <-event: //web request
req := e.req
// do something
....
select {
case <-ctx.Done():
//log
default:
e.replyTo <- result
}
}
}

// Web handler
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
//decode request etc
...

replyTo := make(chan interface{}, 1)
ctx, cancel := context.WithCancel(context.BackGround())
event <- Event{req: req, ctx: ctx, replyTo: replyTo}
select{
case <-time.After(time.Second):
cancel()
//return 500
case r := <-replyTo:
// return some response
}
})


I do see that there is one single go-routine at the end, so parallelism is lost but I am okay with it.



Is this pattern the right way of doing this?
What other approaches can be suggested?










share|improve this question
























  • What are you trying to accomplish? Why not just use net/http?
    – Flimzy
    Nov 18 at 8:48










  • I am using net/http... the handler function is delegating the work to goroutine which has data
    – Saurav Prakash
    Nov 18 at 8:49










  • "Is this pattern the right way of doing this?" -- the right way of doing what? You still haven't explained your goal. Why go to all this effort to seemingly undermine the standard library, and make your code less efficient?
    – Flimzy
    Nov 18 at 8:53








  • 1




    The handler function doesnt have enough state to handle request..It delegates it to another goroutine which has the required data procured from some other place. is that what you are trying to achieve?
    – Shank
    Nov 18 at 8:55












  • @Shank Yes exactly
    – Saurav Prakash
    Nov 18 at 8:57













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am writing a web application where I have a long running goroutine.
I want to delegate all HTTP requests to this goroutine via channels.
The pattern that I have come across is:



// Internal long running goroutine
for{
select{
case e := <-event: //web request
req := e.req
// do something
....
select {
case <-ctx.Done():
//log
default:
e.replyTo <- result
}
}
}

// Web handler
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
//decode request etc
...

replyTo := make(chan interface{}, 1)
ctx, cancel := context.WithCancel(context.BackGround())
event <- Event{req: req, ctx: ctx, replyTo: replyTo}
select{
case <-time.After(time.Second):
cancel()
//return 500
case r := <-replyTo:
// return some response
}
})


I do see that there is one single go-routine at the end, so parallelism is lost but I am okay with it.



Is this pattern the right way of doing this?
What other approaches can be suggested?










share|improve this question















I am writing a web application where I have a long running goroutine.
I want to delegate all HTTP requests to this goroutine via channels.
The pattern that I have come across is:



// Internal long running goroutine
for{
select{
case e := <-event: //web request
req := e.req
// do something
....
select {
case <-ctx.Done():
//log
default:
e.replyTo <- result
}
}
}

// Web handler
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
//decode request etc
...

replyTo := make(chan interface{}, 1)
ctx, cancel := context.WithCancel(context.BackGround())
event <- Event{req: req, ctx: ctx, replyTo: replyTo}
select{
case <-time.After(time.Second):
cancel()
//return 500
case r := <-replyTo:
// return some response
}
})


I do see that there is one single go-routine at the end, so parallelism is lost but I am okay with it.



Is this pattern the right way of doing this?
What other approaches can be suggested?







go






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 18 at 8:47









Flimzy

36.1k96496




36.1k96496










asked Nov 18 at 8:12









Saurav Prakash

1029




1029












  • What are you trying to accomplish? Why not just use net/http?
    – Flimzy
    Nov 18 at 8:48










  • I am using net/http... the handler function is delegating the work to goroutine which has data
    – Saurav Prakash
    Nov 18 at 8:49










  • "Is this pattern the right way of doing this?" -- the right way of doing what? You still haven't explained your goal. Why go to all this effort to seemingly undermine the standard library, and make your code less efficient?
    – Flimzy
    Nov 18 at 8:53








  • 1




    The handler function doesnt have enough state to handle request..It delegates it to another goroutine which has the required data procured from some other place. is that what you are trying to achieve?
    – Shank
    Nov 18 at 8:55












  • @Shank Yes exactly
    – Saurav Prakash
    Nov 18 at 8:57


















  • What are you trying to accomplish? Why not just use net/http?
    – Flimzy
    Nov 18 at 8:48










  • I am using net/http... the handler function is delegating the work to goroutine which has data
    – Saurav Prakash
    Nov 18 at 8:49










  • "Is this pattern the right way of doing this?" -- the right way of doing what? You still haven't explained your goal. Why go to all this effort to seemingly undermine the standard library, and make your code less efficient?
    – Flimzy
    Nov 18 at 8:53








  • 1




    The handler function doesnt have enough state to handle request..It delegates it to another goroutine which has the required data procured from some other place. is that what you are trying to achieve?
    – Shank
    Nov 18 at 8:55












  • @Shank Yes exactly
    – Saurav Prakash
    Nov 18 at 8:57
















What are you trying to accomplish? Why not just use net/http?
– Flimzy
Nov 18 at 8:48




What are you trying to accomplish? Why not just use net/http?
– Flimzy
Nov 18 at 8:48












I am using net/http... the handler function is delegating the work to goroutine which has data
– Saurav Prakash
Nov 18 at 8:49




I am using net/http... the handler function is delegating the work to goroutine which has data
– Saurav Prakash
Nov 18 at 8:49












"Is this pattern the right way of doing this?" -- the right way of doing what? You still haven't explained your goal. Why go to all this effort to seemingly undermine the standard library, and make your code less efficient?
– Flimzy
Nov 18 at 8:53






"Is this pattern the right way of doing this?" -- the right way of doing what? You still haven't explained your goal. Why go to all this effort to seemingly undermine the standard library, and make your code less efficient?
– Flimzy
Nov 18 at 8:53






1




1




The handler function doesnt have enough state to handle request..It delegates it to another goroutine which has the required data procured from some other place. is that what you are trying to achieve?
– Shank
Nov 18 at 8:55






The handler function doesnt have enough state to handle request..It delegates it to another goroutine which has the required data procured from some other place. is that what you are trying to achieve?
– Shank
Nov 18 at 8:55














@Shank Yes exactly
– Saurav Prakash
Nov 18 at 8:57




@Shank Yes exactly
– Saurav Prakash
Nov 18 at 8:57












1 Answer
1






active

oldest

votes

















up vote
1
down vote














Is this pattern the right way of doing this?




Assuming you are trying to manage where state in a single go routine, I would say no. I think it would be better to have some form of a state manager that is responsible for thread safety. Therefore the handler should take in something that can manage the state and simply expose a few methods to the handler.



type State interface{
Load() (string, error)
Save(something string) error
}


Decoupling the code will pay off for you later on. It will also allow unit tests for both the handler and the State that can be focused and readable.






share|improve this answer























  • Doesn't the channel guarantee thread safety? The channel is being read by 1 single goroutine and hence at any point of time, it would service a single request.
    – Saurav Prakash
    Nov 18 at 9:21










  • Yes it can. However my point is that the pattern of having the handler take on thread safety is not great decoupling of concerns. If later you decide the channels are non-performant, you would want the ability to refactor without having to rewrite every single part.
    – poy
    Nov 18 at 9:25











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53359006%2fpattern-for-handling-http-requests-via-channels%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote














Is this pattern the right way of doing this?




Assuming you are trying to manage where state in a single go routine, I would say no. I think it would be better to have some form of a state manager that is responsible for thread safety. Therefore the handler should take in something that can manage the state and simply expose a few methods to the handler.



type State interface{
Load() (string, error)
Save(something string) error
}


Decoupling the code will pay off for you later on. It will also allow unit tests for both the handler and the State that can be focused and readable.






share|improve this answer























  • Doesn't the channel guarantee thread safety? The channel is being read by 1 single goroutine and hence at any point of time, it would service a single request.
    – Saurav Prakash
    Nov 18 at 9:21










  • Yes it can. However my point is that the pattern of having the handler take on thread safety is not great decoupling of concerns. If later you decide the channels are non-performant, you would want the ability to refactor without having to rewrite every single part.
    – poy
    Nov 18 at 9:25















up vote
1
down vote














Is this pattern the right way of doing this?




Assuming you are trying to manage where state in a single go routine, I would say no. I think it would be better to have some form of a state manager that is responsible for thread safety. Therefore the handler should take in something that can manage the state and simply expose a few methods to the handler.



type State interface{
Load() (string, error)
Save(something string) error
}


Decoupling the code will pay off for you later on. It will also allow unit tests for both the handler and the State that can be focused and readable.






share|improve this answer























  • Doesn't the channel guarantee thread safety? The channel is being read by 1 single goroutine and hence at any point of time, it would service a single request.
    – Saurav Prakash
    Nov 18 at 9:21










  • Yes it can. However my point is that the pattern of having the handler take on thread safety is not great decoupling of concerns. If later you decide the channels are non-performant, you would want the ability to refactor without having to rewrite every single part.
    – poy
    Nov 18 at 9:25













up vote
1
down vote










up vote
1
down vote










Is this pattern the right way of doing this?




Assuming you are trying to manage where state in a single go routine, I would say no. I think it would be better to have some form of a state manager that is responsible for thread safety. Therefore the handler should take in something that can manage the state and simply expose a few methods to the handler.



type State interface{
Load() (string, error)
Save(something string) error
}


Decoupling the code will pay off for you later on. It will also allow unit tests for both the handler and the State that can be focused and readable.






share|improve this answer















Is this pattern the right way of doing this?




Assuming you are trying to manage where state in a single go routine, I would say no. I think it would be better to have some form of a state manager that is responsible for thread safety. Therefore the handler should take in something that can manage the state and simply expose a few methods to the handler.



type State interface{
Load() (string, error)
Save(something string) error
}


Decoupling the code will pay off for you later on. It will also allow unit tests for both the handler and the State that can be focused and readable.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 18 at 9:39









Flimzy

36.1k96496




36.1k96496










answered Nov 18 at 9:16









poy

5,61753262




5,61753262












  • Doesn't the channel guarantee thread safety? The channel is being read by 1 single goroutine and hence at any point of time, it would service a single request.
    – Saurav Prakash
    Nov 18 at 9:21










  • Yes it can. However my point is that the pattern of having the handler take on thread safety is not great decoupling of concerns. If later you decide the channels are non-performant, you would want the ability to refactor without having to rewrite every single part.
    – poy
    Nov 18 at 9:25


















  • Doesn't the channel guarantee thread safety? The channel is being read by 1 single goroutine and hence at any point of time, it would service a single request.
    – Saurav Prakash
    Nov 18 at 9:21










  • Yes it can. However my point is that the pattern of having the handler take on thread safety is not great decoupling of concerns. If later you decide the channels are non-performant, you would want the ability to refactor without having to rewrite every single part.
    – poy
    Nov 18 at 9:25
















Doesn't the channel guarantee thread safety? The channel is being read by 1 single goroutine and hence at any point of time, it would service a single request.
– Saurav Prakash
Nov 18 at 9:21




Doesn't the channel guarantee thread safety? The channel is being read by 1 single goroutine and hence at any point of time, it would service a single request.
– Saurav Prakash
Nov 18 at 9:21












Yes it can. However my point is that the pattern of having the handler take on thread safety is not great decoupling of concerns. If later you decide the channels are non-performant, you would want the ability to refactor without having to rewrite every single part.
– poy
Nov 18 at 9:25




Yes it can. However my point is that the pattern of having the handler take on thread safety is not great decoupling of concerns. If later you decide the channels are non-performant, you would want the ability to refactor without having to rewrite every single part.
– poy
Nov 18 at 9:25


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53359006%2fpattern-for-handling-http-requests-via-channels%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Costa Masnaga

Fotorealismo

Sidney Franklin