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

Possibility of custom process registration dispatching logic? #27

Open
Qqwy opened this issue May 31, 2017 · 7 comments
Open

Possibility of custom process registration dispatching logic? #27

Qqwy opened this issue May 31, 2017 · 7 comments

Comments

@Qqwy
Copy link

Qqwy commented May 31, 2017

Right now, it is possible to either return a PID, or to register using :global or :via. However, this needs to be given as option when ExActor.GenServer is included (used).

This unfortunately which means that it is impossible to build custom logic, to e.g. register at {:via, Registry, {MyRegistry, "user_#{user_id}"}}.

Maybe, a possibility would be to allow users to write a custom export function, which is used for the different functions to transform the first argument into a term like above that could be used to do the actual GenServer dispatching on.

@sasa1977
Copy link
Owner

sasa1977 commented Jun 1, 2017

It is possible to use via tuple by using private macros (defstartp, defcastp, ...), but this requires additional wrapping, and pretty much makes ExActor as noisy as GenServer. I discussed this in #26.

Your proposal is very interesting, and at first glance I like it. We could support a callback function (e.g. server_pid/1), which would by default be an identity function. It could be overridable, so in the implementation you can override the behaviour and turn it into e.g. a via tuple. The function should be invoked only if export option is not provided.

Would you be willing to make a PR? The code is somewhat convoluted, what with all the macro logic, so if you don't feel like it, I could give it a stab.

@Qqwy
Copy link
Author

Qqwy commented Jun 1, 2017

Yes, I am willing to give the creation of a PR a go :-).

@sasa1977
Copy link
Owner

sasa1977 commented Jun 1, 2017

Good luck :-) If you get stuck somewhere, feel free to ask.

@Qqwy
Copy link
Author

Qqwy commented Jun 1, 2017

I think the cleanest way would be to just define server_pid as a normal function that can be overridden (by ExActor specifying defoverridable [server_pid: 1]) by the user. Do you agree?

@sasa1977
Copy link
Owner

sasa1977 commented Jun 1, 2017

Yeah, that's what I thought as well.

@Qqwy
Copy link
Author

Qqwy commented Jun 10, 2017

All right.

I worked a little bit on this today, as I finally had some spare time.

However, I'm still unable to find the proper location to add the new logic.

I am guessing it is close to Exactor.Operations.server_ref/2, but I am unsure what server refers to in the quote(do: server) statements. (Is this a snippet that is inserted somewhere else in an unhygienic way?)

@sasa1977
Copy link
Owner

I pushed a small refactoring commit into a separate branch. With that change, the definition of the interface function for calls/casts is now done in the single place.

Roughly speaking, you need to do the following. If type is neither :multicall nor :abcast, and :export option is nil or false, you need to do something along the lines of:

  1. Split gen_server_args into head/tail (outside of the quoted block).
  2. Inside the quoted block invoke the new callback with injected head from step 1.
  3. Modify the invocation in line 587 and pass the result from step 2 followed by unquote_splicing(tail_from_step_1).

If type is :multicall or :abcast, or :export option is neither nil nor false, you should use the same quoted code as in line 587. So you'll add an if before line 586, and then either return the verbatim copy of the existing quote block, or a more elaborate quote block as described above.

I didn't try this out, so I might have missed some possible problems or fine-print details :-)

You can cherry pick my commit into your branch, and then try to see if my proposal takes off.

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

No branches or pull requests

2 participants