celluloid / celluloid

Actor-based concurrent object framework for Ruby
MIT License
3.88k stars 273 forks source link

pluggable/extendable actors registry ? #309

Closed acds closed 11 years ago

acds commented 11 years ago

The registry is obviously a powerful structure of Celluloid; however given that it currently supports just a simple name it would be good to be able to extend it to the application domain, and allow and extensible classification mechanism. Actors could then be filtered based on said classification and enumerated.

Current one need to concoct a naming scheme and pass all the names to filter the desired list.

In an domain model where there are multiple actors representing different constructs this would be really useful.

I'd propose that to keep the base implementation on Celluloid clean, that the Registry is just made pluggable, so that users of the library can extend it easily.

tarcieri commented 11 years ago

The ability to inject a custom registry was added in 122a998cce61416a5f0c77a4875cd09bc13c1086

acds commented 11 years ago

Hi @tarcieri thanks for the pointer...I did not find the reference in the documentation. I don't suppose there are any documented "requirements" for an injected implementation ? I assume one just subclasses Celluloid::Registry, creates and instance and pass it into ones SupervisorGroup#run ?

As an aside, the https://github.com/celluloid/celluloid/wiki/Registry wiki documentation has a broken link a the bottom of the page referencing the Celluloid::Registry

tarcieri commented 11 years ago

Some documentation is probably in order ;) But yes, that's the general idea. You should be able to pass in any duck type of Celluloid::Registry, not necessarily a subclass

acds commented 11 years ago

It would be good if the RSepc had an alternate sample than just passing in the standard implementation...I'll have a go as putting something together.

From what I can tell I need to substitute something else in for the name in all references to the @registry hash. The name would be expose as a formatted representation of the keys

However I probably need to see all the places that reference the registry internally, and ensure they get the expected interface. I expect the registry key in my scenario is derived of immutable state of each actor and its class.

tarcieri commented 11 years ago

If you get it working to your satisfaction, please consider adding some info to https://github.com/celluloid/celluloid/wiki/Registry ;)

halorgium commented 11 years ago

@acds I'm not sure you should be holding too much state in the registry. Have a look at the future of registries to see how things are heading.

acds commented 11 years ago

Some initial research is showing that although the registry is injectable, the key is forced in many place to being name the principal aspect of which it seems an injectable registry would want to change ?

I also seems that there is a need for registration to be made up of two parts, the registry container, and the registrations themselves that map to each actor. With the default registration modeling a name. However I expect that that injectable extension would also need to combine registration attributes into a canonical name (and that this model should be reflexive).

In terms of state, I figure my registry would allow me to derive registrations based filter actors based on their class, a single unique attribute of the actors state that is immutable once the actor is created, and some additional context tiring back to its linked parent up to the actors members managed by its supervisor. I took at look at the tree gist, and would extend that so that a canonical name would represent an actors place in that structure.

It also seems that event though the registry is injectable it the implementation is perhaps (given my current understanding of the code) still tied to the default behavior. In lib/celluloid/actor.rb:

   def_delegators "Celluloid::Registry.root", :[], :[]=

Won't this need to be modified to pick up the custom registry to reference Celluloid::SupervisionGroup::Registry.root where Registry is an accessor to the `@registry class member, otherwise it seems the actor code will delegate to the default registry ?

Areas of research include for potential impact:

As I did deeper I'm probably going to uncover more; but also learn the celluloid code-base better.

I'm interested in giving this a go as a learning experience; but figure I may need some help....any takers ?

tarcieri commented 11 years ago

@acds I'd really like to see a concrete example of what you want to use in lieu of naming. The Registry is supposed to be a DNS-like system for mapping human-meaningful names to actors. What are you planning on replacing it with?

Also be sure to check out halorgium's link

acds commented 11 years ago

@tarcieri Per @halorgium's link, this is the general model I'd had in mind. Where the name is a canonical representation of an actor within that structure, with a uniquely distinguishing identification values included at each level based on the Actor (and its purpose).

I found I was creating a string mask and inserting the place holders before registering each actor. This does not seem very efficient or clean.

Today I'd retrieve all the actors names, and parse them to find the ones I care about in a specific context.

However in recognition, that its on the Core Ideas as an Overhaul, it may be more than I have the skills, background or time to accomplish, especially looking at all the tentacles I'm finding in the code to factor in an alternate solution not based on "name".

concrete == code ? I'm still at the conceptual stage. To be honest would not know from an implementation perspective how to put it together just now.

When one create an actor an Initializes, it should set read_only values that uniquely identifies the actor its own context, coupled with the Class of the Actor and its type. Perhaps there is a class constant that references the method or properties that make up that identification so it can be overridden on an actor class basis. This will be used in the name scheme, appended to to the equivalent of its creation parent (how is this determined ?) to develop a canonical name indicating a logical path to the actor through the hierarchy from root, for example:

root.user.supervisor_group-<class>-<identifier>.supervisor-<class>-<identifier>.actor-<class>-<identifier>.actor-<class>-<identifier>...

Based of this construct one could query the structure based of say the Actor class or other elements.

At any place in the hierarchy the actors below it can be referenced in terms of their relative canonical names, and be able to use these elements provide a filter, that can span the entire hierarchy from that point.

From an Actor once would be ale to retrieve the registration and use the to query the registry from that context, navigate, or initiate other actor management activities.

Each actor is automatically registered and the registry forms a hierarchy of Registration objects leveraging an existing tree gem (that is thread safe, and not rails specific like ancestry; but similar semantics) that has all the navigation constructs built in, the registration holds a reference to the actor, and will self mange based on the lifetime of the actors and its children. I guess the registrations are System scoped Actors and would leverage the linking.

The Registration picks up the identification from the created Actor as part of it's initialization process so its completely automatic.

The Registration will raise an exception if the initialization properties have not been initialized, will check for duplicates (perhaps add an incrementor to distinguish them). The initialization properties would be frozen as part of completing the registration.

In terms of DCell, the registration can also be extended to determine "where" the actor is, etc.

This obviously could also tie into the the Notifications components in terms of registering for topics.

I hazard a guess the tree structure also lend itself to a dashboard and a restful management/monitoring interface that is also on the ToDo list.

Given how these aspects tie together it might be good to get this nailed down more, and hope my input is valuable ?

Thanks for the engaging thread.

halorgium commented 11 years ago

@acds @tarcieri I recommend we take this to the ML. I'd be interested in talking about this in more depth. You should probably look at the akka naming scheme, it has some interesting ideas which we are drawing from.