Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Tag: design

To Actor or not to Actor, that is the Question

When I first starting playing around with Akka, I was definitely swimming upstream. I was learning Scala and learning Akka and coming from a very non-functional, non-actor-oriented background. The more I learned about Scala and the more I learned about Akka, I started noticing some places where I had made rather large architectural mistakes.

One thing that I did with Akka 1.x was I exposed public state properties on various actors. While this fixed my problem, it was a bad smell that I didn’t notice at the time. In my ScalaMUD sample, I switched and used an implicit that wraps an external hash map to maintain state of actors. I now even think this is a bad idea and in a new project (yet to be disclosed) I am currently trying to avoid exposing -any- public state on any actors.

The current challenge that I seem to be running into is in figuring out the level of granularity of my actor system. In other words, how do I decide when to create more actors or when to do the work necessary within a def  as a plain Scala function?

I’ve come up with the following set of questions that I ask myself now:

  1. Should this work take place concurrently?  If the work in question is something that I think should be fired off in the background, then this is a huge argument leaning toward the use of an Actor.
  2. Do multiple other actors need this service performed? If the code I’m about to put into a function is something that other actors in the system also need done, then I should really consider using an Actor that performs the work on demand by receiving a message rather than a function. That said, keep in mind that multiple Actors can all make use of shared Scala objects/classes – so re-evaluate the problem against other criteria in this list as well.
  3. Is this operation purely synchronous or request/response? If so, then you might not need or want to use an actor for it. Sure, there is plenty of syntactical support for request-and-await-reply blocking calls in Akka but the more of those you do, the uglier and harder to read your code gets. If you really need to perform a synchronous, blocking functional call then it might be better as a function and not an Actor.
  4. Is this really a data storage/retrieval operation? If the work you’re considering offloading to an Actor is actually data storage like putting and getting from hash tables or something similar then you might not need an Actor for it. That said, if the act of storing or retrieving might take a while and you don’t want to block during this, sending a message to a “data actor” and going about your business might actually be the best thing for it.
  5. Does my current Actor respond to too many messages? One thing I’ve noticed during my work with ScalaMUD is that I’ve created Actors that do too much. Actors, in my experience, seem to be work better the smaller and more purpose-built they are. The actor system has a robust supervisory system that makes actors that control other actors not only possible, but a best practice. I’ve gotten tremendous value from refactoring one big Actor into multiple smaller actors.
  6. Do I need supervisory control over a service that is being performed? As mentioned above, if there is some service that needs to be performed but you want control over how your application reacts to failures like exceptions, then using a supervisor and wrapping that service as an Actor and setting a control policy can do you a world of good. For example, you can set it so the supervisor receives messages when the child throws an exception, or you can have Akka automatically restart dead child actors. The possibilities are as powerful as they are varied.
  7. Does this operation need to be thread-safe? If the answer is yes, then you might want to use an actor. The reason for this is that actors pull their messages out of queues in a single thread, which means no work you do in response to receiving a message is ever re-entrant, so you don’t need locks or critical sections. This alone is quite possibly one of the single biggest advantages of actor-based programming and design.

Obviously your mileage may vary and I am still an Akka/Scala newbie but what I have found, especially with my newest project, is that my application almost designs itself automatically when I think in terms of autonomous, supervisory-linked actors rather than thinking in terms of traditional OOP.

I recently tweeted the following statement and I still believe it is true: Actors are to OOP what OOP was to procedural programming.

Adding State to Actors with the Pimp My Class Pattern

In my last blog post, I talked about how the new Akka 2.0 actor system hides an enforces the inaccessibility of the actual class of the underlying actor. For example, if you have a class called Zombie that is of type Actor, then when you use the actor system to start that actor, what you get back is an ActorRef, and (without cheating), there is no way to typecast or otherwise gain access to the Zombie type from an instance of ActorRef. While it felt limiting, once I embraced the design principle that necessitated that enforcement, I understood.

That said, I am building a MUD here and I’m going to need state. My rooms need names, descriptions, and exits. My NPCs are going to need combat stats and inventories, my players are going to need names, descriptions, races, genders, etc. This is all basic stuff but – if I can’t get to a game object reference from an ActorRef, how am I going to get at their internal state?

Easy! Don’t use internal state.

Remembering back to my first post where I upgraded my old Scala MUD to use Akka actors, I noted that every actor in a system has a unique path string that denotes its position within a hierarchy of supervisory actors much like the way supervisors and processes exist in an Erlang system. That gave me the idea to store the state for my actors in a big in-memory hash (which I could then upgrade to some kind of distributed or CouchDB-type store later).

With that problem solved, the only real problem now was that my ActorRef instances didn’t have concrete properties. One of my favorite features of Scala, which is also used in building DSLs, is the pimp my class or pimp my library pattern. This works very much like class extensions in C#. I can create a class that encapsulates or enriches an underlying class type by providing methods that operate on or with that class. In my case, I wanted strongly typed accessors like name and description that actually deferred the backing store to this singleton, in-memory hash.

Here’s my scala file that contains an Implicits object that enriches the ActorRef type with the wrapper class and the wrapper class provides a getter and setter for name.

package com.kotancode.scalamud.core

import akka.actor.ActorRef
import scala.collection.mutable.{Map,
    SynchronizedMap, HashMap}

object Implicits {
	implicit def enrichActorRef(value: ActorRef) = new WrappedActorRef(value)
}

/*
 * Singleton containing a hash map keyed on the Actor Ref path
 * which contains additional hash maps.
 * There is one hash map for every actorref that needs state
 */
object StateMap {

   // Creates a thread-safe hash map
   def makeMap: Map[String, HashMap[String,String]] = {
       new HashMap[String, HashMap[String,String]] with
           SynchronizedMap[String, HashMap[String,String]]
   }

   private var stateMap = makeMap

   def getState(key:String):HashMap[String,String] = {
   	 if (!stateMap.contains(key))
	     stateMap.put(key, new HashMap[String,String])
	 stateMap(key)
   }

   def setState(key:String, propertyName:String, value:String) = {
		var state: HashMap[String,String] = null
		val result = stateMap.get(key)
		result match {
			case Some(x) => state = x
			case None => state = new HashMap[String,String]
		}
		state.put(propertyName, value)
		stateMap.put(key, state)
   }
}

class WrappedActorRef(val actorRef: ActorRef) {

	def name:String = StateMap.getState(actorRef.path.toString)("name")
	def name_=(value:String) { StateMap.setState(actorRef.path.toString, "name", value) }
}

An obvious refactoring opportunity here would be to move the StateMap class out to its own separate Scala file but I’ve always been a huge fan of the agile process of getting something working first and refactoring afterward.

Now, to use my newly enhanced ActorRef (with state) class all I have to do is add the following import

import com.kotancode.scalamud.core.Implicits._

To the top of my Scala file and below anywhere the type ActorRef is known, I can read and write the name property, as shown here:

	private def handlePlayerLogin(player:ActorRef) = {
		println("Player logged in: " + player)
		allPlayers ::= player
		for (p: ActorRef <- allPlayers) {
			p ! TextMessage(player.name + " logged in.")
	    }

Because ActorRef has been pimped to use the external state provider, I can use player.name in my code and it works!

You spilled some OOP in my Actor System!

Lately I’ve been doing a lot of experimenting and playing with Scala and Akka. I’ve been building a MUD to give me a goal as I learn the language, the framework, and the intricacies involved.

So far I’ve been focused mostly on syntax and learning what idiomatic Scala looks like, how to create and use Akka actors, and so on. It wasn’t until the other night that I started thinking about design and philosophy. This mini-revelation came about when I spent hours trying to find a way to get the actual type from underneath an ActorRef.

I was using context.actorOf() to create actors, as one should with Akka 2.0. So I might be creating and starting actors for rooms, monsters, or living room tables – anything that I thought might be instructive to mess around with. This is when I noticed that once you create an ActorRef by adding your actor to the actor system (either via system.actorOf or context.actorOf) you can’t get at the actual class underneath. All you can do is interact with it like an actor-shaped black box by sending and receiving messages.

In other words, let’s say I’ve got a class called Zombie that is an actor that I’ve added to the actor system. The Zombie has properties like name, eatingSpeed, and percentLivingTissueRemaining. With regular Scala actors, I would’ve been able to mix and match classic OOP-style programming with actor-style programming:

println(tehZombie.name)
tehZombie.percentLivingTissueRemaining = 12
tehZombie ! FeedUpon(randomVictim)

At first this might look nice and appealing, but there’s something insidious happening here. First, our code has access to the internal state of tehZombie for both reading and writing. Secondly, we can send actor-style messages to tehZombie. Back during my first attempt at a MUD using regular Scala actors, I regularly abused this capacity – reading public fields from instances of actors all the while sending them messages.

One main purpose of an actor system is to take the complexity away of multi-threaded access to shared state and business logic. If we have one actor able to access another actor using standard OOP-style member-access patterns, we’ve basically ruined all of the advantages we’re getting from the actor system to begin with because access to public state on an object is not inherently thread-safe.

If we change internal state on an Akka actor in response to a message, we are guaranteed that such a state change is thread-safe. Not only is it thread-safe, it’s single-threaded because the actor’s inbox is being processed by that actor’s thread (or thread pool) and no one else.

So what does this mean? It means that, within the context of an actor system, public state and OOP-style member access is BAD.

Unfortunately, what this means for my MUD is that I’ve got some refactoring to do because I noticed that I’ve been cheating and I passed around a reference to this to another actor – which gave that actor “unsafe” access to public members of my class. What I really should be doing is making sure that nothing on my actors is exposed publicly and I should be aiming for a message pure environment where everything works as though actors are black boxes that just receive messages, do what they need to do, and send back out messages to other actors within the system.

Akka 2.0 enforces an awful lot of this by suppressing access to this from other actors (I cheated… bad, bad, Kevin). Hopefully within a few days (after the Giants win the Super Bowl) I will have some refactoring checked into the Github repo that hopefully has a fully functioning system that is clean, message pure, and exposes no unsafe members.

Wish me luck 🙂

Spacial Schemas and Cognitive Engineering

In a previous post, I shared some of my initial thoughts on what appears to be a new, more rigorous discipline for designing interfaces called Cognitive Engineering. Cognitive Engineering is all about using information from many different areas of science to feed an engineering discipline designed to produce interfaces with very small impedance between a user’s mental model and the form and function of the application.

One of these many areas of science involves something called spatial schemas. Our minds are incredibly good at dealing with the concept of space. From the moment our senses first start being processed by our mind, our mind is constantly constructing spatial models. These spatial schemas can aid in everything from memory to locomotion to pathfinding and even to logic.

We take for granted how pervasive spatial schemas and referential spatial models are in our daily lives. For example, when we compare two abstract concepts we often do so by gesturing with one hand and then saying, “… on the other hand, …”. Without a built-in spatial schema in our mind to represent the difference between the left and right sides of our bodies, can you imagine that a comparison like this would be easy?

Another fascinating example of how spatial schemas help us is with models that have been so burned into our consciousness that we can actually compare stimuli against those models before performing the relatively slow step of cognition.

For example, if you’re a soldier (or play one in a video game) and someone near you shouts “on your 5!”. Your body will have already started the 150 degree turn necessary to turn to “your 5”. This happens in around 10 milliseconds whereas it takes over 300ms for a stimulus to make a round-trip through your conscious mind. Why is this possible?

It’s because the stuff that happens unconsciously (the high-performance part of your mind, the part of your mind that has spent hundreds of millions of years evolving to help you survive long enough to continue the species) can do a rapid comparison against a retained spatial schema… that of an analog clock.

Our brains are actually quite good at determining direction (angles) and even if we don’t know how or why, we are aware of subtle differences in angles even down to 1 degree. So when someone shouts “on your 5” the high-speed portion of your brain is already encoding the mapping between 5 on an analog clock to the 150 degree turn into signals to send to your muscles to accomplish this… and it does this all before your conscious mind has processed that because from an evolutionary standpoint, if your conscious mind was responsible for mapping spatial schemas to survive, you’d be dead. It takes less than 300ms for an animal to jump out “from your 5” and start mauling your dumb, hairless butt.

So what does this have to do with interface design?

It seems obvious when you think about it but you need something (like this informative, albeit dry, textbook) to get you thinking about it. Knowing how the brain constructs spatial models and knowing how these spatial models aid memory, logic, reasoning, and comparison will help you build interfaces that take advantage of this.

Interfaces built this way can “cheat” … if you differentiate things spatially, a user won’t have to waste valuable cognitive time processing that differentiation. For example, if a user sees “A > B” on the screen, that little blurb has to go all the way through to their slow brain (cognition) to figure out that A is greater than B, which will create a spatial model in their head representing the two objects.

How much work do you think your brain has to do if object A appears physically higher on the screen relative to B? None. That display model maps exactly to the spatial model that the brain would have constructed as a result of the slow round-trip to parse “A>B”.

What if one object is bigger than another one, visually? What if one object appears far to the left while others appear far to the right? What if an object is rotated ever-so-slightly? All of these spatial representations of entities can be designed to map the spatial model that we expect a human brain to create from more obtuse, less informative interfaces … so why not save the user the effort and create that model ahead of time, right there in the interface.

Assign meaning to space, size, spatial relationships, directionality, curvature, velocity … all of these things can be used to create amazing interfaces, not because they will be pretty or shiny, but because they will not slow the user down and will not force their minds to do work they don’t need to be doing.

Anyway, as I said in the other blog post I haven’t yet really tried to use any of these techniques to build user interfaces but I have seen the results of similarly engineered interfaces and it is really powerful stuff.  Hopefully reading this blog has made you think a little bit more about the role interfaces play and how they interact at a chemical, biological, neurological level with our users.

First Impressions of Cognitive Engineering

This week I’ve been receiving some training in what appears to be the relatively new field of Cognitive Engineering. This training comes from Brad Paley of didi.com.

Hopefully all of us computer professionals are aware of the importance of user interface. However, many designers confuse “prettiness” with “usefulness” and many developers think that a simple grid view or spreadsheet should suffice because rows and columns are a perfectly acceptable model for that data.

I’ve known for quite some time now that spreadsheets are an evil abomination and force our brains to do things that they should not have to do for 8 hours a day but haven’t really had the tools, machinery, or vocabulary to articulate why. Thanks to this class, I believe I now have the vocabulary to articulate why one interface design is better than another.

The core of this discipline is the notion that an expert at some particular job function has a mental model of the entities and tasks involved in accomplishing their job. It is our responsibility as designers using Cognitive Engineering to extract their mental model and use techniques and information from a half dozen fields of science completely unrelated to computers in order to produce a design that provides a user experience model that has little to no impedance between their mental model.

To summarize, the user should be able to look through their user interface and the widgets with which they interact on screen should not only come as close as possible to their mental model but, perhaps more importantly, the interface should be designed in such a way that as much pre-cognitive processing as possible can be done by the user.

We know which tasks take the brain a long time to do. We know which tasks increase cognitive load. We know what things human cognition, the human eye, our ears, our spatial processing system are all adept at. The key to this discipline is using all of that information to guide the design process. If we can design an interface such that a user can rapidly categorize, sort, associate, and parse most of it in the 10s of milliseconds of time the brain spends before involving conscious thought, then users will be able to plow through their job tasks with insane productivity using software designed this way.

They will feel less fatigued after using software designed this way and probably won’t even know why. They should be able to sit in front of this software and because they are an expert in their domain, the screen should so closely resemble their mental model of their job that they should be able to just work.

They won’t be thinking about clicking, mouse dragging, typing, searching, or right-clicking. They’ll be thinking about completing orders, shipping boxes, canning tuna – the software disappears in service of their job.

At least, that’s the promise of this discipline. I’ve seen much of this thinking in Cooper’s Interaction Design field and there is a lot of overlap here.  The focus of cognitive engineering is really on the physical, chemical mechanics involved in the brain’s information processing and reaction capabilities and using that science to inform design.

I haven’t yet used this discipline to produce a UI by extracting an expert’s mental model yet but, for the first time in a long time, I can’t wait to try this out and produce a design. It’s a rare thing that a few quick sessions can inspire this much interest in me but this has and only time and experience will tell if it produces a better product.

Easy Patching Does Not Excuse Lazy Coding

Lately it seems that virtually all of the software we have on our desktops and mobile devices is easily updated. Back in the day, the prime argument for building web applications as opposed to full-on client applications was that web applications could be updated instantly; push an update to the server and all your web users get the new experience. This model is now applicable to desktop and mobile applications as well. These applications check servers for newer versions, alert you when there’s an update, download it, and even install the new update for you. Your iPhone or Windows Phone 7+ or Android device also knows when Apps have been updated, and you can download those updates easily and wirelessly.

The problem with this kind of easy patching target is that more and more, I hear developers and even management saying things like “oh, we’ll just patch it later.” I suppose that’s an OK argument for some environments. Web 2.0 startups (as well as Google and others) practically invented the concept of the “perpetual beta”. The perpetual beta is that in exchange for getting a product shipped earlier, the product ships in a beta state where patches and updates to the product can (and often do) happen on a daily basis.

The downside to this is that your user base becomes your testers. Certainly not in all cases, but in a scary number of instances you start seeing less and less up-front testing because the developers have gotten used to their users reporting bugs, they fix the bugs, they push a new update. What I don’t like about this is that we’re training users to expect faulty software and we’re training developers to expect users to be the first reporters of problems. These are both, in my opinion, inexcusable.

If you want to call your software a perpetual beta then fine, call it that. But don’t let your users replace your QA team. You should still be reasonably sure that your software is stable and solid, and you’re using this beta period to gather feedback. Feedback is not the same as a bug report. As more and more shops go through this cycle of build-vomit-patch, there is high risk for software and its associated user experience to be just plain awful.

Take, for instance, this photograph below. It is of a VoIP telephone in use by a very large, very well-known hotel chain. Take a look at the time displayed in the top of the photograph. The time, according to this phone, is 0:12am. What? Are you kidding me? How could something like this possibly have made it past a QA process? I realize that a simple bug like displaying the time wrong (it’s either 00:12 without am or pm or it’s 12:12am, basic clock display logic that we’ve been using for decades). As soon as I saw this on the phone, the first thing that came to my mind is the fact that these phones are easy to patch. Push a button, the phones are told of a patch, they self-reboot, download a new image, and the update is complete. This is not an excuse for lazy coding.

Bad Phone UX

Bad Phone UX

So, the point of this blog isn’t to complain that my phone had a bug in it. The point is to complain that I’ve been noticing a trend lately, a trend where the amount of testing done on an application is becoming inversely proportionate to the availability of a quick and easy patch deployment mechanism.

As the title of the blog post says, easy patching does not excuse lazy coding.

Hubs vs. Apps, UX Patterns in Mobile Devices (WP7 vs iPhone)

Before I get started here I want to clarify that the idea of hubs isn’t unique to Windows Phone 7. In fact, the Palm Pre has had hub-like functionality since day one and there are other platforms, other devices, and other OSs that all have hubs or something similar. For the rest of this blog post, however, I will be talking about WP7 hubs and how they have the potential to radically alter the way we can interact with our device and our data.

WP7's Marketplace Hub

WP7's Marketplace Hub

It’s all about control. In a traditional, app-centric system the application has complete control and the user must go through it in order to get at any piece of information. In a hub-centric system, the information is in control and apps (or even small pieces of apps) are summoned at will to do things with, for, or related to, that information.

WP7 People Hub

WP7 People Hub

Let’s take an example. Let’s say I want to e-mail someone a photo, and this person is only in one of my social network applications. In an app-centric system you’d probably reach for your e-mail client first. But, on the iPhone, you can’t actually start in your mail app to send attachments. I know, seems odd. So, you go to the photos app, which lets you e-mail the photo. But, the contact list is only the list of contacts that are on your phone’s internal contact list. It doesn’t look up people in facebook or LinkedIn or MyAwesomeSocial or anywhere else. What if I want to tweet the photo after I e-mail it? On an app-centric platform, I have to back all the way out of the photo app, go into the Twitter app, and then pick the photo from the “new tweet” menu. If I want to then share the photo on facebook, what do I have to do? Escape all the way to the home screen again, and then open up the Facebook app, then push a few buttons and the worst part of this, is that I have to re-find the item that I was originally hoping to share on Facebook.

WP7 Game Hub

WP7 Game Hub

Now let’s look at how this might work in a hub-centric system. You go into the photos hub and then you find the photo you want. Without ever leaving the context of this photo, the system knows which applications are able to add extension capabilities to that photo. This means that from this photo, you can send it to someone via e-mail, you can share it on Facebook, you can share it on Twitter, you can (and yes, this is real, I’ve seen this in screenshots) automatically treat the photo with the word “FAIL” and submit it to the FAIL blog. And because contacts are also a hub, contacts can be injected into the list by other applications that know of additional sources of people. This means that from the photos hub, I can e-mail the photo to someone whose e-mail address came from Facebook or LinkedIn or the corporate directory or wherever.

WP7 Pictures Hub

WP7 Pictures Hub

Think about it this way: What you use your smart phone for, the things that you deal with on a daily basis, is data. Information. The applications are merely there to provide just enough chrome and ceremony to allow you to manipulate and store that information in a way that is hopefully pleasant and meaningful. Given this statement of roles and responsibilities, I personally feel that the hub-centric approach to smart phone UX is absolutely, hands-down more productive than the app-centric UX.

In addition to all of the built-in hubs that come with WP7, developers can even create their own. This enables application-sharing scenarios across multiple vendors and enterprises. Developers for a single enterprise can also build an entire hub around the business of that enterprise – aggregating data and information and statistics and wrapping all that information with functionality that applies to the information, only loosely identifiable as “apps”.