Deprecated
NOTE – as of 20 Nov 2017, Ephemeral exchange is migrating to a Firestore/ Firebase cloud function back end. See Migrating from App Engine to Cloud function

Ephemeral Exchange is a cross platform cache with a REST API and some useful SDK clients for various platforms. In this example I’ll look at how to use intents to preserve cache atomicity, and the code demo platform will be Apps Script. 

Intentions

There are times when you are sharing cache across apps that there may a conflict where two processes try to update the same data item. The full write up on how this works in on github, where you’ll also find the node and JavaScript client. The Apps Script client is here.

The console

You’ll need to register and create a boss key in the API console. That will allow you make access keys for the store.

Generate a boss key

First off we’ll need a writer key. For collaboration purposes you’d probably also create a reader and an updater, but we’ll just stick to a writer for this demo.  To create access keys, you need a boss key. You can make one in the API console, or use an existing one, and copy it to use in your script.

Initialize the API

Add the library – it’s reference is 

19rhki6VDTWk4v1RDb6u1d5E-nNaQq8sXCnRnFzUpp4V4lmZ9Z6R_PP9n

then 

 // set up client shortcut 
  var efx = EffexApiClient;
  
 // boss key comes from console /// replace this with your own
 var bossKey ="bx2be-4fe-egoeibbk21k1";

 Check service is up if you want

var result = efx.ping();
  if (!result.ok) throw 'problem with the service:' + result.error;

Create a writer key

 //get an access key
  var result = efx.generateKey (bossKey, "writer");
  if (!result.ok) throw 'problem with the service:' + result.error;
  
  // store that for later
  var writer = result.keys[0];

Write a data item

// write something
  var result = efx.write ("something",writer);
  if (!result.ok) throw 'problem with writing :' + result.error;
  
  // save for later
  var id = result.id;

If you want to read it back normally, with no intention to update

// read it back normally
  var result = efx.read (id, writer);
  if (!result.ok) throw 'problem with reading :' + result.error;

But you can also read it back, with an intention to update it shortly

// read it back but put a hold on it
  var result = efx.read (id, writer, {intention:"update"});
  if (!result.ok) throw 'problem with intention reading :' + result.error;

And it returns an intent key. Now no-one else but this access key and this intent key can update it for a short while

 // save it for later
  var intent = result.intent;

If you to write it you’ll get an error

// try to write to it without the intention, it'll fail
  var result = efx.update ("some more data", id, writer);
  if (result.ok) throw 'should have blocked update';
    // save this for later
  var intentExpires = result.intentExpires; 

Here’s what an error looks like

// take a look at the result
  Logger.log(result); 

{accountId=2be, code=409, intentExpires=20, lifetime=3600, modified=1.490893678846E12, id=dx2be-5cr-et9wbg2e12b6, ok=false, error=item is locked by another key, plan=x, updater=wxk-oe1-u1kdw2ezbbhx}

This time it will allow the update since we are passing the intent key as well

 // .. or if you do it with the intent
  var result = efx.update ("some more data", id, writer, "post" , {
    intent:intent
  });
  if (!result.ok) throw 'problem with intention updating :' + result.error;

If you don’t have an intent key, then it means someone else is working through the process of updating, so you have to wait.  When it rejected your request it also told you the time you’d need to wait to be sure the other guy was finished, or his lock expired.

// if you want to wait till its available
   Utilities.sleep (result.intentExpires * 1000 );
   var result = efx.update ("some more data", id, writer);
   if (!result.ok) throw 'lock should have cleared :' + result.error;

Where to get it

To use the store console, just visit the console and login with your google ID. No other registration is required. See this documentation for how to use the API and Ephemeral Exchange for more info, examples and demos.