#3072 - add UID to RemoteActorRef

61 views
Skip to first unread message

Patrik Nordwall

unread,
Mar 12, 2013, 9:03:20 AM3/12/13
to akka...@googlegroups.com
I have explored the beginning of two alternative ways. Both commits cause test failures, so this is only for discussion and decision.

Alt 1: uid as an explicit parameter, and only in ActorRef, no change to ActorPath. This was a good exercise to see what parts are involved. It keeps the uid as a rather internal thing, but it makes things more complicated than alt2.


Alt2: uid as part of ActorPath. Less changes. More magic, but also more elegant. Exposes the uid in string representation.
https://github.com/akka/akka/commit/4f258c7523c577e24568333a119d04c7c3e224cf


WDYT?

--

Patrik Nordwall
Typesafe The software stack for applications that scale
Twitter: @patriknw

√iktor Ҡlang

unread,
Mar 12, 2013, 9:07:09 AM3/12/13
to akka...@googlegroups.com
Looking at the end result I think I prefer Alt2, I also like how you chose the fragment instead of a parameter as it looks way cleaner.

Great job Patrik!


--
You received this message because you are subscribed to the Google Groups "Akka Developer List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Viktor Klang
Director of Engineering

Typesafe - The software stack for applications that scale
Twitter: @viktorklang

Roland Kuhn

unread,
Mar 12, 2013, 9:51:33 AM3/12/13
to akka...@googlegroups.com
Good to see two fleshed-out proposals, thanks Patrik!

I like the second one because it retains one of the properties which I had in mind when introducing the URI-based path syntax back in 2011, namely that each actor is identified by its path (or more precisely that a path uniquely identifies an actor; there may be more than one path representing the same actor). This makes it very obvious where the UID needs to be generated, which is precisely where the “name tag” is minted. Everything else then basically falls into place.

Regards,

Roland

--
You received this message because you are subscribed to the Google Groups "Akka Developer List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Empowering professional developers to build amazing apps.
twitter: @rolandkuhn

Patrik Nordwall

unread,
Mar 12, 2013, 10:04:09 AM3/12/13
to akka...@googlegroups.com
Thanks! It's probably no surprise that I also like the second alternative.

I'm a bit worried if there is a chance that the uid is lost in places where it shouldn't, such as in RemoteActorRef.getChild.

What do you think about the equals and compareTo as Endre and I talked about here: https://github.com/akka/akka/commit/5560f1defdc6efe628948799544420b857ae7d26#commitcomment-2786983
Is it even possible to treat undefinedUid as a wildcard match in equals and compareTo? Does that violate the contract of those methods?

Roland Kuhn

unread,
Mar 12, 2013, 10:34:43 AM3/12/13
to akka...@googlegroups.com
12 mar 2013 kl. 15:04 skrev Patrik Nordwall:

Thanks! It's probably no surprise that I also like the second alternative.

I'm a bit worried if there is a chance that the uid is lost in places where it shouldn't, such as in RemoteActorRef.getChild.

That should be covered by tests (in this case RemoteCommunicationSpec IIRC).


What do you think about the equals and compareTo as Endre and I talked about here: https://github.com/akka/akka/commit/5560f1defdc6efe628948799544420b857ae7d26#commitcomment-2786983
Is it even possible to treat undefinedUid as a wildcard match in equals and compareTo? Does that violate the contract of those methods?

Hmm, that is a good questions. First of all compareTo and equals need to be compatible with each other. Then having a wildcard basically means that transitivity of the ordering relation is broken because while a == b == c you can still have a < c if b==wildcard. Is that a problem for sorting algorithms? We need to consider what happens if you put ActorRefs into collections.

I tend to think that equality should not have a wildcard, just as compareTo currently does not have it, and that we only apply the wildcard behavior when looking up child actors.

Regards,

Roland

Patrik Nordwall

unread,
Mar 12, 2013, 10:42:55 AM3/12/13
to akka...@googlegroups.com
On Tue, Mar 12, 2013 at 3:34 PM, Roland Kuhn <goo...@rkuhn.info> wrote:

12 mar 2013 kl. 15:04 skrev Patrik Nordwall:

Thanks! It's probably no surprise that I also like the second alternative.

I'm a bit worried if there is a chance that the uid is lost in places where it shouldn't, such as in RemoteActorRef.getChild.

That should be covered by tests (in this case RemoteCommunicationSpec IIRC).


What do you think about the equals and compareTo as Endre and I talked about here: https://github.com/akka/akka/commit/5560f1defdc6efe628948799544420b857ae7d26#commitcomment-2786983
Is it even possible to treat undefinedUid as a wildcard match in equals and compareTo? Does that violate the contract of those methods?

Hmm, that is a good questions. First of all compareTo and equals need to be compatible with each other. Then having a wildcard basically means that transitivity of the ordering relation is broken because while a == b == c you can still have a < c if b==wildcard. Is that a problem for sorting algorithms? We need to consider what happens if you put ActorRefs into collections.


yes, that is probably asking for trouble
 
I tend to think that equality should not have a wildcard, just as compareTo currently does not have it, and that we only apply the wildcard behavior when looking up child actors.

We should base equals/compareTo on the path elements and the uid or only on the path elements.
Would it be wrong/surprising to ignore the uid in equals/compareTo?
We can think about it.

Patrik Nordwall

unread,
Mar 12, 2013, 1:12:28 PM3/12/13
to akka...@googlegroups.com
When fixing failing tests I realize that it's probably not feasable to include the uid in the toString representation of ActorPath because if users concatinate paths they will be invalid.
e.g. "akka://ActorLookupSpec/user/c2#-27780829/c21"

I will exclude it from toString, but add another public method toRawString that includes it. That will be used for the serialized representation.

Ok?

Roland Kuhn

unread,
Mar 12, 2013, 4:02:36 PM3/12/13
to akka...@googlegroups.com
12 mar 2013 kl. 18:12 skrev Patrik Nordwall:

When fixing failing tests I realize that it's probably not feasable to include the uid in the toString representation of ActorPath because if users concatinate paths they will be invalid.

I will exclude it from toString, but add another public method toRawString that includes it. That will be used for the serialized representation.

The serialized representation is already created via toStringWithAddress, IIRC, and I believe it would be enough to have that emit the UID. Leaving it out of .toString would match making ActorPath.uid private[akka] (which it should if I’m right about assuming that there is no user-level API which accepts UID as input).

In addition we could make it configurable whether the loggernames shall contain the UID or not, defaulting to “not”.

Regards,

Roland

Rich Dougherty

unread,
Mar 15, 2013, 12:10:00 AM3/15/13
to akka...@googlegroups.com
Hi Patrik

There's something about the proposed design that doesn't seem quite right to me, as I'll explain below. I have an alternative suggestion. I'm not sure how practical my suggestion is, but I'd be interested in your thoughts. I'm sure I'll learn something either way.


Actors are often created without names. In this case they are given random names (actually just an incremented long).


In the new design, such an actor still gets a random name. But now it also gets a random uid.


So now we will often have new actors with two random identifiers. This seems awkward to me and makes me wonder if another design might be a bit cleaner…

I'd argue that if we were building an actor system from scratch (i.e. we weren't refactoring existing code) then we wouldn't use the proposed hybrid path/uid design. Instead (I think) we'd design our system to use a single identifier to identify actors among their siblings.

We've already worked out that actor names aren't good unique identifiers, since users can reuse them. That's why we're making this change after all. So I would suggest that the primary identifier should be an internal system-generated id.

If each actor gave each of its children a unique system-generated numeric id then a uid could be formed by following a sequence of ids from the root actor, e.g. something like "/7/12/252/59/7". This is very similar to the current actor paths, except it is a sequence of digits instead of names, and it's system generated so guaranteed to be unique for each actor.

Collisions could be trivially avoided by using a counter to generate unique ids at each level (in the same manner as "random" names are currently generated).

Once we have a system-generated id, we would entirely drop the requirement that actors need to have a name. They were only compulsory before because they were required to look up actors.

However names are still possible, albeit optional. This can easily be added on top of numeric ids, with a map. Each actor would include a map of ids to children, and also a map of names to ids. Many actors will not need names at all so the extra indirection shouldn't be too burdensome. Plus we could use an int-specialized map for most work, which would be faster and more compact.


So there's the sketch of a fairly radical idea. Let me know what you think!

Cheers
Rich

Roland Kuhn

unread,
Mar 15, 2013, 3:22:23 AM3/15/13
to akka...@googlegroups.com
Hi Rich,

thanks for bringing this up, it is always good to weigh alternatives (a wise man said that then you know that you did not pick the worst possible solution).

What you are proposing is to fold the random name of unnamed actors into their UID, and to use UIDs for look-up.

Let’s first regard the second part: where does look-up happen? Currently the user can trigger it using actorFor, which is completely name-based in the sense that you cannot really look up actors which you didn’t name explicitly (including all their parents); actorFor is going to be replaced with actorSelection, but that does not change this picture, which means that we will have to support name-based lookup in the future. The other place where look-up happens is when a node receives a message from an external entity such as the remoting layer and needs to deserialize the ActorRefs contained within (including the envelope). This look-up is purely internal and could potentially benefit from being numeric for performance reasons as well as serialized message size (since most actor names are longer than four octets when serialized). Given the steady flow of remoting-related questions on the mailing list and our dependency on readable debug output I don’t think we can abandon human-understandable names in the remoting layer; we tried using GUIDs in the 1.x series and that was provably not a good idea. It might be possible to allow switching the serialized representation from names to UIDs in order to gain performance, though; it sounds like an interesting optimization akin to foregoing debuggability of C programs by switching on -O3 (or some such).

For the first part: it would indeed be interesting to be able to leave out the name and use the path’s UID, that is another optimization for saving a few bytes, and it is particularly interesting because unnamed actors tend to be the short-lived leaves of a hierarchy. My best guess is that most of the actor classes you write will be of the named kind, but the unnamed ones will probably be the most often instantiated ones. We very clearly recommend that actors shall have nice names wherever practical.

One thing you did not mention: the String representation of ActorRefs and ActorPaths needs to be meaningful, offering a string of digits interspersed with slashes is not going to make people happy. I’d say that this is an API requirement, but it does not necessarily mean that the implementation needs to be completely name-based.

Regards,

Roland

Rich Dougherty

unread,
Mar 15, 2013, 4:06:45 AM3/15/13
to akka...@googlegroups.com
Hi Roland

Names could still be used and displayed to the user when they're used, but we would make names optional and make the id the primary identifier.

Imagine the actor with a location consisting of two explicit names and two random names. Its path is currently something like:

/foo/bar/$a/$1c

And its proposed internal representation would be something like:

(name=foo,uid=1238123),(name=foo,uid=12839123),(name=$a,uid=12981233),(name=$1c,uid=981293)

I'm suggesting that the name become optional. So the internal representation woudl change to something like:

(name=foo,id=3),(name=bar,id=5),(id=10),(id=28)

But notice that it can still be displayed in the same way, if we so choose:

   /foo/bar/$a/$1c

We could even allow lookup on this if we wanted, to preserve existing actorFor semantics. Of course, actors containing system-generated path elements would only rarely be looked up; usually they'd be referenced by ActorRef.

So mainly I'm making a point about the internal representation and the duplication between random names and random uids. Now that we have random ids we can drop the random names IMO. The user-visible semantics could stay largely the same.

Cheers
Rich

Roland Kuhn

unread,
Mar 15, 2013, 4:21:00 AM3/15/13
to akka...@googlegroups.com
Is that not precisely what I said?

As far as I can see the currently proposed implementation has everything that is needed and it allows the optimizations which we just now discussed. Since we agree that user-visible behavior is not going to change we are free to try these out at a later time. Could you please open tickets so we don’t forget to?

Thanks,

Roland

Rich Dougherty

unread,
Mar 15, 2013, 4:35:26 AM3/15/13
to akka...@googlegroups.com
Ah OK, in that case I think all your points are excellent ones. :)

I'll raise a ticket. But, if this is something we're interested in, then we need to be careful that we don't move the API in incompatible ways with any of the ref equality, toString and path parsing changes. I think we're OK, but just something to keep in mind.

Cheers
Rich
Reply all
Reply to author
Forward
0 new messages