Get ActorRef of a mutiple akka Actor instances by path - akka

I am creating a pool of instances of a same Actor
Later in my app, I want to be able to reference a specific instance of an actor "pool" by its unique path.
val instance1 = context.spawn(ActorA(), "actorA_1")
val instance2 = context.spawn(ActorA(), "actorA_2")
val instance3 = context.spawn(ActorA(), "actorA_3")
etc
This is done at the initialisation of the application and the goal is to allow any actor of the app to reference this instance if it knows its unique path...
I want to achieve something like that :
val actorRef = getActorByItsUniquePath(path)
actorRef ! sendMessage(...)
I don't know if I need to use the classic Actor Api or the typed API (receptionist) and/or if I need to store the unique path (path + UID) of each Actor instance on a HashMap and retrieve this path later.
I don't find any clear direction to implement that in the doc.

You are on the right path. In Classic Actors this is done by actor selection and Actor Path. Note that "unique path" potentially has to include the node in a clustered setup.
In typed Actors you would use the Receptionist and the ServiceKey acts as your "unique path".
So, you don't need to use one API or the other: you should use classic actors or typed actors as you prefer. Just choose the discovery method (ActorPath or Receptionist) based on which API you have chosen.
However, I will add one caveat. Generally it is preferred not to do this. You are effectively exposing an implementation detail to your client. And removing some flexibility/resiliency. This is discussed here in the docs: https://doc.akka.io/docs/akka/current/actors.html#identifying-actors-via-actor-selection under "It is always preferable to communicate with other Actors using their ActorRef instead of relying upon ActorSelection. Exceptions are:". This is not to say that you absolutely shouldn't do this, as the actor discovery APIs obviously exist for a reason. Just that you should "prefer" not to depending on looking up actors via unique path, and that you should have a good reason for not using something like a router instead.
EDIT TO REPLY TO COMMENT:
You say in the comment below that you will have actor instances with the same path, but this impossible. Actor paths are unique*; each instance has a unique path. It seems that you may think that the path is associated with the actor, but the path is the actor instance. See the docs and also see the section in the Classic docs about naming actors where it talks about the fact that you must give a unique name to each instance. If you don't explicitly give a unique name to your instance, the system will auto generate one. (e.g. /user/myactor/$1, /user/myactor/$2, ...)
If you do have a uid generated already, just specify it as the name of instance when you spawn it and you will end up with a path that looks like: akka://my-actorsystem#mynode:port/user/parentactor/youruid and you will be able to use that path to look it up.
You situation really isn't that unusual. This is a pretty common pattern to have many instances of the same actor, each maintaining state. This is also why I mention using a router pattern, because you have more flexibility with that design. In fact, this is also basically the pattern behind Akka Sharding. You may want to look into that as an option as well, especially if you are using clustering.
If you use a Receptionist and typed actors it's basically the exact example shown in the Receiptionist docs. Every time you create a new actor instance you would register it with the Receptionist with the register message and your uid key. Then you just look it up later with a Find message. It's a wee bit more complicated because Receptionists don't enforce uniqueness (unlike Paths) and because you have to be aware of types (and therefore adapt response types) but that's all the Receptionist really is: a key-value store of actor instances implemented as an actor you send messages to.
*Technically, actor paths are unique to living actor instances. You, in theory could create an actor /user/foo, stop it, and then create a second instance with the same name. But I didn't want to complicate the above explanation as I didn't think that detail was important here.

Related

Django: How to depend on an externally ID, which can be switched?

Consider the following scenario:
Our Django database objects must rely on IDs that are provided by external service A (ESA) - this is because we use this ID to pull the information about objects that aren't created yet from the external directly. ESA might shut down soon, so we also pull information about the same objects from external service B (ESB), and save them as a fallback.
Because these IDs are relied on heavily in views and URLs, the ideal scenario would be to use a #property:
#property
dynamic_id = ESA_id
And then, if ESA shuts down, we can switch easily by changing dynamic_id to ESB_id. The problem with this though, is that properties cannot be used in queryset filters and various other scenarios, which is also a must in this case.
My current thought is to just save ESA_id, ESB_id, and dynamic_ID as regular fields separately and assign dynamic_ID = ESA_id, and then, in case ESA shuts down, simply go over the objects and do dynamic_ID = ESB_id.
But I feel there must be a better way?
Having ESA_id and ESB_id fields in the same table is a good solution, then you have some kind of setting (DEFAULT_SERVICE_ID='ESA_id'|'ESB_id') and your code change the lookup based on this option.
Here you can see an aproach to create filters dynamicly
https://stackoverflow.com/a/310785/1448667

Route entry condition in C++

I am using omnet++ to change a specific route entry for a multicast group address. Usually, a multicast route entry is added by using the best (shortest) route to the source of the message.
However what I need to do is to modify this behavior for a specific multicast address so that it does not take the shortest path to source condition but instead uses "first entry".
What I mean is that, if after flooding the multicast packet (with no multicast route entry before) received on a router via three interfaces with the time of arrival like this: 1.eth0 2.eth1 3.eth2, it automatically sets interface eth0 as the RPF and does not compute whether this is the best path.
The normal behavior was already coded into omnett but when I found the functions to add new routes I do not understand where are the conditions of adding a new route.
internalAddMulticastRoute
AddMulticastRoute
As far as I understand, the methods you posted don't actually check anything with regards to which interface is used: whenever a multicast route is added, it is simply stored and used. You might want to have a look at where addMulicastRoute is called; there might be code there that controls priorities. The code in internalAddMulticastRoute only organizes the routing table (which is kept sorted through upper_bound). If you want to control which interface is used, you'll need to modify the routing table entries. I'd recommend performing a check before calling addMulticastRoute.

How to achieve MVCC in actor model

Let's say I have represented my Employee entity as an actor. I have 2 services also modeled as actors. Both of them manipulate the state of an Employee actor it has received by sending it messages. Now let's say both the services are processing the same actor. Now it is perfectly possible that an employee actor receive state changing messages in the following order from the two services A and B
Employee <- |a1|a2|a3|b1|b2|b3|
This is fine. But sometimes its not
Employee <- |a1|b1|a2|b2|a3|b3|
Maybe a2 was dependent on state changed by a1, but b1 changed it
In analogy to databases, we have transactions so that we can work with a single snapshot/version of the data throughout the transactions lifetime.
In imperative model, we would lock the whole employee object and update its state similar to how database would do it.
So is it possible that an actor can receive bulked messages that will be processed as one atomic series of messages? Or is my modeling of my data itself flawed?
Since I don't know what a1-a3 and b1-b3 actually represent, I can only assume to answer the question correctly. To me it appears that your messages are too fine grained. For example, perhaps a1-a3 are trying to set just one attribute of data in each message. The same probably goes for b1-b3.
However, what your messages should be focused on is causing behaviors on the Employee, not in setting individual attributes. Thus, as you yourself suggest, design your messages as behaviors, where a1-a3 would collapse into a single operation request. This is often called the Command pattern, where you command/tell an object/actor to do something. Doing so will result in correct transactional boundaries per message.
Note that above I said "object/actor." You can/should use the same approach in your object designs, not just for actors. Think in terms of intention-revealing interfaces and telling your domain model what you want it to do for you, rather than treating domain objects/actors as dumb data holders.
That's my take on your question. HTH.
Vaughn
Both of them manipulate the state of an Employee actor it has received
by sending it messages.
Well. An Actor by definition does not share its state or its manipulation with any other Actor. Any state manipulation is transactional within the boundaries of one message handling. An Actor represents an aggregate in that sense. Messages usually are Domain events/commands and have scope and part of the Ubiquitous language.
DDD reasoning helps a lot when thinking about Actors.
My two cents
Sergiy
<><

TMG SF_NOTIFY_POLICY_CHECK_COMPLETED Event

According to http://msdn.microsoft.com/en-us/library/ff823993%28v=VS.85%29.aspx, during this event the web filter can request GUID of the matching rule. I am assuming that is done by performing a GetServerVariable with type of SELECTED_RULE_GUID, since I could find no other readily identifiable means of doing so.
My problem comes from the fact that I want to see if the rule is allowing or blocking the request. If it's being blocked then my filter doesn't have to take any action, but if it's being allowed I need to do some work. SF_NOTIFY_POLICY_CHECK_COMPLETED seems to be the best event to watch, since it occurs last enough that authentication and various ms_auth traffic has been handled, but just before the request either gets routed or fetched from cache.
I had thought that perhaps I needed to use COM and the IFPC interfaces (following along with example code for registering Web Filters to TMG) to get details on the rule. However, going down via FPC -> FPCArray -> FPCArrayPolicy -> FPCPolicyRules, the only element-returning function takes either an index or a name.
Which is problematic given that I only have a GUID.
The FPCPolicyRule object (singular) doesn't seem have any field related to GUID either, which eliminates just iterating over the collection for it.
So my question boils down to, from the SF_NOTIFY_POLICY_CHECK_COMPLETED event, how would a web filter determine if the request has been allowed or denied?
After more investigation and testing, the GUID is accessible via the PersistentName of the FPCPolicyRule object. Since FPCPolicyRules->Item member only works on either Name or Index, I had to iterate through its items comparing each PersistentName against the GUID.
Apologies if this was obvious, took me a good day to work out :)

How to solve two REST problems: the interface document; loss of privacy in descriptive URLs

Coming from a lot of frustrating times with WSDL/Soap, I very much like the REST paradigm, but am trying to solve two basic problems in our application, before moving over to REST. The first problem relates to the lack of an interface document. I think I finally see how to handle this situation: One can query his way down from a top-level "/resources" resource using various requests of GET, HEAD, and OPTIONS to find the one needed resource in the correct hypermedia format. Is this the idea? If so, the client need only be provided with a top-level resource URI: http://www.mywebservicesite.com/mywebservice/resources. He will then have to do some searching and possible keep track of what he is discovering, so that he can use the URIs again efficiently in future to do GETs, POSTs, PUTs, and DELETEs. Are there any thoughts on what should happen here?
The other problem is that we cannot use descriptive URLs like /resources/../customer/Madonna/phonenumber. We do have an implementation of opaque URLs we use in the context of a session, and I'm wondering how opaque URLs might be applied to REST. The general problem is how to keep domain-specific details out of URLs, and still benefit from what REST has to offer.
The other problem is that we cannot use descriptive URLs like /resources/../customer/Madonna/phonenumber.
I think you've misunderstood the point of opaque URIs. The notion of opaque URIs is with respect to clients: A client shall not decipher a URI to guess anything of semantic meaning from it. So a service may well have URIs like /resources/.../customer/Madonna/phonenumber, and that's quite a good idea. The URIs should be treated as opaque by clients: not infer from the URI that it represents Madonna's phone number, and that Madonna is a customer of some sort. That knowledge can only be obtained by looking inside the URI itself, or perhaps by remembering where the URI was discovered.
Edit:
A consequence of this is that navigation should happen by links, not by deconstructing the URI. So if you see /resouces/customer/Madonna/phonenumber (and it actually represents Customer Madonna's phone number) you should have links in that resource to point to the Madonna resource: e.g.
{
"phone_number" : "01-234-56",
"customer_URI": "/resources/customer/Madonna"
}
That's the only way to navigate from a phone number resource to a customer resource. An important aspect is that the server implementation might or might not have domain specific information in the URI, The Madonna record might just as well live somewhere else: /resources/customers/byid/81496237. This is why clients should treat URIs as opaque.
Edit 2:
Another question you have (in the comments) is then how a client, with the required no knowledge of the server's URIs is supposed to be able to find anything. Clients have the following possibilities to find resources:
Provide a search interface. This could be done by providing an OpenSearch description document, which tells clients how to search for items. An OpenSearch template can include several variables, and several endpoints, depending on what you're looking for. So if you have a "customer ID" that's unique, you could have the following template: /customers/byid/{proprietary:customerid}", the customerid element needs to be documented somewhere, inside the proprietary namespace. A client can then know how to use such a template.
Provide a custom form. This implies making a custom media type in which you explicitly define how (based on an instance of the document) a URI to a customer can be forged. <customers template="/customers/byid/{id}"/>. The documentation (for the media type) would have to state that the template attribute must be interpreted as a relative URI after the string substitution "{id}" to an actual customer ID.
Provide links to all resources. Some resources aren't innumerable, so you can simply make a link to each and every one of them, optionally including identifying information along with the links. This could also be done in a custom media type: <customer id="12345" href="/customer/byid/12345"/>.
It should be noted that #1 and #2 are two ways of saying the same thing: Clients are allowed to create URIs if they
haven't got the URI structure a priori
a media type exists for which the documentation states that URIs should be created
This is much the same way as a web browser has no idea of any URI structure on the web, except for the rules laid out in the definition of HTML forms, to add a ? and then all the query parameters separated by &.
In theory, if you have a customer with id 12345, then you could actually dispense with the href, since you could plug the customer id 12345 into #1 or #2. It's more common to actually provide real links between resources, rather than always relying on lookup or search techniques.
I haven't really used web RPC systems (WSDL/Soap), but i think the 'interface document' is there mostly to allow client libraries to create the service API, right? if so, REST shouldn't need it, because the verbs are already defined and don't really need to be documented again.
AFAIUI, the REST way is to document the structure of each resource (usually encoded in XML or JSON). In that document, you'll also have to document the relationship between those resources. In my case, a resource is often a container of other resources (sometimes more than one type), therefore the structure doc specifies what field holds a list of URLs pointing to the contained resources. Ideally, only one unique resource will need a single, fixed (documented) URL. everithing else follows from there.
The URL 'style' is meaningless to the client, since it shouldn't 'construct' an URL. Every URL it needs should be already constructed on a resource field. That let's you change the URL structure without changing the client (that has saved tons of time to me). Your URLs can be as opaque or as descriptive as you like. (personally, i don't like text keys or slugs; my keys are all BIGINTs or UUIDs)
I am currently building a REST "agent" that addresses the first part of your question. The agent offers a temporary bookmarking service. The client code that is interacting with the agent can request that an URL be bookmarked using some identifier. If the client code needs to retrieve that representation again, it simply asks the agent for the url that corresponds to the saved bookmark and then navigates to that bookmark. Currently those bookmarks are not persisted so they only last for the lifetime of the client application, but I have found it a useful mechanism for accessing commonly used resources. E.g. The root representation provides a login link. I bookmark that link and if the client ever receives a 401 then I can redirect to the "login" bookmark.
To address an issue you mentioned in a comment, the agent also has the ability to store retrieved representations in a dictionary. If it becomes necessary to aggregate and manipulate multiple representations at the same time then I can simply request that the agent store the current representation in a dictionary associated to a key and then continue navigating to the next resource. Once the client has accumulated all the necessary representation it can do what it needs to do.