Homam's Mind

Thursday, March 11, 2010

Mutually Dependent Systems

In this post I am discussing a problem that I have faced several times in the past year. Simplicity is always a goal in design as it saves resources during development and maintenance. But it's not always clear which design is simpler. Sometimes a seemingly complex design turns out to be simpler to develop, maintain and extend.

In a master-slave architecture, assume S1 is the master. It produces one or more tasks form a given job and transfers them to S2 (the slave); S2 does the tasks and return the results back to S1. S2, the slave, depends on S1, the master.


If the next time that S1 assigns a task to S2 it uses the information that exists in the result of a previous task that had been assigned to S2 then S1 also depends on S2 and we have a mutually dependent couple.

In our terminology the systems are mutually dependent if and only if S1 uses the information it gained as a result of a previous task that it had already assigned to S2. It doesn’t matter if S2 has completed the previous task or not, but it should have reported something to S1 that is useful for S1 for a next assignment of a task to S2.

If S1 is only using the fact that S2 is busy or free then we don't call it a mutual dependency. S1 must use the information that is generated by processing a task at S2. For example a MapReduce system is not a mutually dependent system.

Why is it important? You should have already guessed that S2 is the name of a class of slave systems that work with S1. There could be many instances of S2. Let's define a homogenous mutually dependent system as a system that in which all slaves of S1 are in the same class.

Two slaves are of the same class if they share a common interface for communicating with S1.

Now assume that S3 is also a slave for S1. S3 is in a different class other than S2 if either its input or its output interface is different from S2's.

When designing mutual dependent systems we have to always decide whether to keep the mutual dependencies or to break them by introducing new nodes. It's mainly a decision over complexity. The other factor that may affect your decision is the swiftness of the system. Introducing a new node will usually reduce the responsiveness.

[caption id="attachment_239" align="aligncenter" width="292" caption="Breaking the mutual dependency by using S4 node. Note that S3 is another class and uses a different interface to communicate with S4."][/caption]

For instance a new node must not be added if S1 waits for S2 to return. Generally you should try to keep the number of nodes as small as possible if the operations are not asynchronous.

Homogenous mutual dependency is OK (when the systems are simple and synchronous) but things get much dirtier as we introduce new classes to the system. On the other hand if extensibility is a goal you should try to avoid mutual dependencies.

For a conclusion, use mutual dependent systems in live systems, when a rapid response is required, and try to avoid them by introducing middle nodes if you have many classes of slaves or if extensibility is a goal.
Thursday, February 18, 2010

Canvas Intellisense in Visual Studio

I was playing with HTML5 Canvas element to see how it could be useful in future web based game developments. I like that it is easier than GDI. I haven't yet done much performance testing but it is definitely faster than making games by animating DOM elements.

Recently I had some free time so I decided to create vsdoc documention for Canvas element interface for Visual Studio. I added intellisense (auto competition) and some helps and tips.

Download canvas-vsdoc.js and canvas-utils.js from CodePlex.



It is tuned to work with VS2010, but we can make it work with VS2008 too.

canvas-vsdoc.js contains the intellisense documentation.

canvas-utils.js has a few utility functions (like detecting if the browser supports Canvas) and some enumeration types for things like Line Joins, Repeations, Text Aligns, etc.

To use the intellisense you need to reference canvas-vsdoc.js in the beginning of your JavaScript file, like this:

/// <reference path="canvas-vsdoc.js" />

Note you can just drop the .js file and Visual Studio will write the reference.

Then use a utility method to get a reference to canvas element:
var canvas = Canvas.vsGet(document.getElementById("canvas1"));

Canvas.vsGet(element) receives a HTML element and returns the given element itself if it is in runtime. But in design time it returns Canvas.vsDoc.VSDocCanvasElement object that contains the documentations.

Then you can use the canvas element as usual:
var ctx = canvas.getContext("2d");
ctx.arc(50, 50, 25, 0, Math.PI, true);

Please note canvas-vsdoc.js must not be included  in runtime but canvas-utils.js should be included (if you want to use Canvas.vsGet() and other utilities).

In VS2008 you should trick the environment by assigning the variable that refers the 2D context to Canvas.vsDoc.Canvas2dContext, by something like this:
var ctx = canvas.getContext("2d");
if (typeof DESIGN_TIME != "undefined" && DESIGN_TIME)
ctx = Canvas.vsDoc.Canvas2dContext;

DESIGN_TIME global variable is defined inside canvas-vsdoc.js. In runtime it should be undefined or false.

Just a note: if you still want to work in IE, you will find this Google extension very interesting: http://code.google.com/chrome/chromeframe/

Update: Visual Studio 11 natively supports canvas intellisense.

 

 

 

 

 

 
Wednesday, February 10, 2010

iframe Cookies in Safari

Older Hyzonia games depend on session and authentication cookies. This dependency has been fixed in the newer games by storing session ID in JavaScript variables. The cookie independent services explicitly require a session ID to be sent by their clients.

In this post I am not going to dig into the details of session management in Hyzonia platform, I just want to highlight a series of problems in the old schema that led us to redesign the session management behavior.

Hyzonia games can be embedded in publishers websites using a piece of code we call Hyzobox. Hyzobox basically renders an iframe in the webpage. The internet domain where the actual game is hosted could be different from the publisher's domain. If you have ever tried this before you know that we gonna have a lot of cross site security issues.

To address cross site scripting issues we developed Hyzobox In/Out API. A publisher can control certain things in the game and be notified about the events that are occurring inside the game using In/Out. It is a JavaScript based solution and strangely is widely supported in all major browsers. The In/Out API is not made public yet, but we are using it extensively in www.hyzogames.com. For instance whenever you win in a game Hyzogames.com will be notified about this event (winning) and may show you a message box.

But cookies are another issue. Different browsers have way different behaviors when it comes to handling cookies in iframes.  For starters for it  to works in IE you need a P3P header like this:

CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"

There's a lot to say here, I have a long standing view that P3P is generally useful but this kind of usage is pointless. Anyway for now just add it in your response and relax.

But still Safari rejects the cookies that iframes try to write. The rationale here is that Safari only wants to write cookies from websites that the user directly visits. It's not a bad idea for privacy. Let's assume that you are visiting a fan website for The Grudge! thegrudgefans.com is using  Google AdSense  (put any evil multibillion dollar internet ad service instead of Google :D) to display you some ads or even just in the background. The AdSense is running inside an iframe and it writes a cookie on your computer indicating you're a fan of nonsense horror teen movies. Now it is written on your face that you're a fan of The Grudge. AdSense can use this cookie anywhere else in the internet. OK you got the idea.

The problem was this privacy feature in Safari was causing our Hyzobox User Integration (a kind of Single Sign On service) to break. Safari users can always turn on a checkbox in the preferences to accept all cookies. But it's not the case by default. The workaround is that the page that writes the cookies must be initiated as a result of a direct user request. Literally meaning that prior to writing any cookie you have to provide a hyperlink (an explicit anchor tag) in your iframe that takes the user to the page that writes the cookie.
Wednesday, January 27, 2010

Overbranding

It's a classic question I ask every UX/UI designer who I interview. What's wrong in this picture?


Tip: The same problem exists here in our own product:



Conclusion: Who cares.