Posted by: Arthur Blake | 2007-10-18

How do fixups work?

How do fixups work?

Straight JSON-RPC and even JSON don’t support or allow circular references.

Typical JSON parsers will cause a stack overflow as they recursively try to process the circular reference over and over again.

We have come up with a simple scheme that we use in jabsorb 1.2:

All circular references are detected and removed from the JSON before being transmitted over JSON-RPC.

An extra parameter is added to the JSON-RPC payload called “fixups”.
These “fixups” are simply a collection of assignment statements that “fix up” the circular references after the main JSON payload is assembled.

An example is perhaps worth 1000 words.

var simpleJson =
{
  project: "JSON-RPC-Java",
  year: 2005,
  site: "http://oss.metaparadigm.com/jsonrpc/"
}

The above object does not contain any circular references and would be serialized by a typical JSON-RPC library like this:

{
  "id": 1,
  "method": "test.myTest",
  "params":
  [
    {
      "project": "JSON-RPC-Java",
      "site": "http://oss.metaparadigm.com/jsonrpc/",
      "year": 2005
    }
  ]
}

Notice above that the outer, enclosing object is a JSON object itself, and contains several “meta” keys with information about the RPC being made. This is standard JSON-RPC stuff.

In this case, a procedure named “test.myTest” on the server is being called, and one parameter (our simpleJson object) is being passed as the payload.

Now suppose we construct another simple json object that has a reference to the first object.

var circJson =
{
  project: "jabsorb",
  year: 2007,
  site: "http://jabsorb.googlecode.com",
  parent: simpleJson
}

and then we create a circular reference like so:

simpleJson.myCircRef = circJson;

Now our simpleJson object would be serialized like this:

{
  "id": 1,
  "method": "test.myTest",
  "params":
  [
    {
      "project": "JSON-RPC-Java",
      "year": 2005,
      "site": "http://oss.metaparadigm.com/jsonrpc/",
      "myCircRef":
      {
        project: "jabsorb",
        year: 2007,
        site: "http://jabsorb.googlecode.com"
      }
    }
  ],
  "fixups":
  [
    [[0,"myCircRef","parent"],[0]]
  ]
}

Notice that the circular reference was removed and replaced with a “fixup”. A fixup can be thought of as an assignment statement.

The “fixups” array contains all the fixup entries that should be applied to the JSON to recreate the circular references on the other side of the RPC call.

Each fixup contains 2 array elements itself. These are themselves arrays, containing the paths to the elements in question. The first path is the path to the element being fixed up and the second path is the path to the original element reference that is being applied to the fix up element. Together these can be thought of as like an assignment statement:

In the above example, [0,”myCircRef”,”parent”] is the “path” to where we want the fixup to be. It could be thought of conceptually as params[0].myCircRef.parent and the left hand side of the equation on an assignment statement.

And [0] is what is being assigned to this original path location. It could be thought of as params[0] and the right side of the assignment statement.

The reason this notation is used to specify paths is that it is extremely simple and fast for a processor to parse and execute these assignment statements in any language. Duplicate objects that are not necessarily circular references can also be passed via this mechanism to more faithfully reconstruct the original object, and can also potentially reduce the overall payload size if many duplicate objects are being passed.

Advertisements

Responses

  1. as an FYI: we had to disable this (set false) due to its reaction to null values. Of note is that we are not using the standard js (jsonrpc.js), which would resolve this on the response from the look of things. Would have made more sense for us if it did not react to the nulls so aggressively.

  2. This was a minor bug in the jabsorb 1.2 release candidate. It’s been fixed in rc2.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: