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?
go
|
show 2 more comments
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?
go
What are you trying to accomplish? Why not just usenet/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
|
show 2 more comments
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?
go
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
go
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 usenet/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
|
show 2 more comments
What are you trying to accomplish? Why not just usenet/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
|
show 2 more comments
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.
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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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