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

Add dispcount:transaction/2 for running funs in watcher context #11

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Vagabond
Copy link
Contributor

To avoid unnecessary calls and waiting for responses allow for a fun to
be passed as a transaction that can be run by the watcher. As soon as
the fun completes, the watcher is marked as free again without
intervention by the calling process. This should improve throughput for
use cases where the caller having direct access to the resource is
not necessary.

This still needs tests, but I have it working in the field.

To avoid unnecessary calls and waiting for responses allow for a fun to
be passed as a transaction that can be run by the watcher. As soon as
the fun completes, the watcher is marked as free again without
intervention by the calling process. This should improve throughput for
use cases where the caller having direct access to the resource is
not necessary.
@Vagabond
Copy link
Contributor Author

Here's how I'm using it, with epgsql's async mode:

  prepared_query(Pool, Name, Params) ->
      Ref = make_ref(),
      Fun = fun(From, {Stmts, Conn}) ->
                    Statement = maps:get(Name, Stmts),
                    #statement{types = Types} = Statement,
                    TypedParameters = lists:zip(Types, Params),
                    %% construct the same kind of cast the epgsqla:prepared_statement does, but redirect
                    %% the output to the elli process directly
                    gen_server:cast(Conn, {{cast, From, Ref}, epgsql_cmd_prepared_query, {Statement, TypedParameters}})
            end,
      case dispcount:transaction(Pool, Fun) of
          ok ->
              receive
                  {_Conn, Ref, Res} ->
                      Res
              after
                  500 ->
                      throw(?RESPONSE_503)
              end;
          {error, busy} ->
              throw(?RESPONSE_503)
      end.

@ferd
Copy link
Owner

ferd commented Apr 1, 2020

Sounds workable; might make sense to identify which request returns which results with a Ref, allowing people to parallelize calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants