Pattern for handling HTTP requests via channels












0














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 '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 '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 '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 '18 at 8:55












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
















0














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 '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 '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 '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 '18 at 8:55












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














0












0








0







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 '18 at 8:47









Flimzy

37.5k96496




37.5k96496










asked Nov 18 '18 at 8:12









Saurav PrakashSaurav Prakash

1249




1249












  • What are you trying to accomplish? Why not just use net/http?
    – Flimzy
    Nov 18 '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 '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 '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 '18 at 8:55












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


















  • What are you trying to accomplish? Why not just use net/http?
    – Flimzy
    Nov 18 '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 '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 '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 '18 at 8:55












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
















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




What are you trying to accomplish? Why not just use net/http?
– Flimzy
Nov 18 '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 '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 '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 '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 '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 '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 '18 at 8:55














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




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












1 Answer
1






active

oldest

votes


















1















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 '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 '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',
autoActivateHeartbeat: false,
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









1















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 '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 '18 at 9:25
















1















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 '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 '18 at 9:25














1












1








1







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 '18 at 9:39









Flimzy

37.5k96496




37.5k96496










answered Nov 18 '18 at 9:16









poypoy

6,43763364




6,43763364












  • 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 '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 '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 '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 '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 '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 '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 '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 '18 at 9:25


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




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

Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

ComboBox Display Member on multiple fields

Is it possible to collect Nectar points via Trainline?