Implement handle_cast and handle_continue #88
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Closes #4
This PR implements the
handle_cast
andhandle_continue
Gen_server methods from Erlang. It also reworks the responses for thehandle_*
methods a bit so thathandle_continue
can be called.Request types
You'll see there are two new request types:
cast_req
andcont_req
. These are separate from the currentreq
type used inhandle_call
(which should maybe be renamed tocall_req
. The reason I added these is becausehandle_call
,handle_cast
andhandle_continue
will have different requests that can be sent to them. It doesn't make sense to be able to send acall
request tohandle_cast
and then having to deal with a potential error/exception if we can prevent it from being valid at all.handle_cast
andhandle_continue
also don't respond to the client, so they also don't need a'res
type.Result types
I also changed
handle_call
to return a newcall_result
type instead to accommodate for the different ways a Gen_server can respond in Elixir.Reply ('res * 'state)
is the regular reply it's been using thus far. But to accommodatehandle_continue
,handle_call
needs to be able to respond with a{:continue, args}
as well like you can do in Elixir. For this I added aReply_continue
as well, which takes the form('res * 'state * cont_req)
, wherecont_req
will be handled byhandle_continue
after the'res
has been sent to the client.Similarly,
cast_result
has aNo_reply
, which is equivalent to the Elixir{:noreply, state}
response. This can be extended for aNo_reply_continue
option as well, or whatever else GenServers in Elixir allows.In Elixir (or Erlang I guess),
handle_call
can respond with a{:noreply, ...}
as well, which assumes that the user manually responded with areply(pid, res)
somewhere in the handler. This is useful for when the reply is known already, but additional work needs to be done by the server. I opted not to implement this, as it leads to potential error states where the user perhaps doesn't do areply
in the handler, or perhaps does tworeply
s. I also think most behaviours requiring this can be implemented withhandle_continue
, which leaves less room for error.