Causeway Platform Developer

From Erights

Revision as of 23:32, 31 May 2010 by Tstanley (Talk)
Jump to: navigation, search

Contents

Instrumenting a Platform to Generate Causeway Trace Logs

Introduction, communicating events loops

  • Waterken
    • promises
  • AmbientTalk
    • futures

Getting Started

  • See Causeway for user documentation, which includes instructions for launching Causeway from a command line shell.
  • See HP Labs Technical Report at www.hpl.hp.com/techreports/2009/HPL-2009-78.html for a more in-depth discussion of the material presented here. A careful read is not necessary but a quick skim to see what's there is a good idea.

This documentation assumes an understanding of the purchase-order example program.

  • Read the source code. It's part of the E distribution and can be found here.
   e/src/esrc/scripts/test/causeway/waterken/sources
   e/src/esrc/scripts/test/causeway/ambientTalk/sources

Also, we're asking that you write a version of the purchase-order example that runs on your platform, as one of your first test cases. It's best to start with the Ajax-style continuation-passing, using callbacks. This approach is less expressive than promises, but generating the trace log is more straightforward.

  • Browse the example programs in Causeway, e.g., Help >> Open Waterken Example (Ajax-style).

Support Tools

  • Enable Causeway's debug view

Setting Causeway's debug flag enables a debug view. As events are selected in the viewer, the debug view shows the corresponding trace record in the log file. This is a very useful option, especially in the beginning, when things aren't quite working.

$ rune -Dcauseway_debug=true causeway.e-swt 


(Note: When this debug option is set, Causeway's JSON parser uses getTwine(). This is an inefficient algorithm which is not likely to change anytime soon. The trace logs for the example programs are roughly 20K; the poor performance is noticed with logs > 250K.)


Image:debug-view.png


  • Support for visualizing graph filter algorithm

Your first traces are likely to be noisy and Causeway's views, baffling. It can take some careful consideration and cleverness to figure out why and what to do about it. Simple filters (e.g., hiding stack frames, options for more or less detail) are necessary but not sufficient. The right abstractions must be found to enhance program understanding, while maintaining causality. Currently, Causeway does not support user-specified filters that manipulate the message graph (DAG) structure. Our approach to debugging our filtering algorithm is described HERE. Once we have more experience, we expect to support user-specified filters.

Causeway's Trace Log Format

Causeway supports the trace log format defined by Tyler Close at waterken.sourceforge.net/debug/.

We will explain this format, and how to get your platform to generate it, in three steps: Simple Ajax (below), Ajax with promotion, and full promises.


Simple event types


When causality tracing is on the events are logged as follows.

Event Record type
An eventual send to an object Sent
A message delivery, starting a new turn Got
Programmer logs a comment Comment

In the Causeway viewer, individual tree items represent events and their descriptive labels depend on the information available in the trace record for the event.


Tree item labels


To present the most useful information available, Causeway labels tree items according to the following priority.

  1. User comments specified in the text field, prefixed with "#".
  2. Source code specified in the top call stack object. The trace object must include a span.
  3. Source file and function name specified in top call stack object. The trace object must include a name and source.
  4. If none of the above, the label is a Causeway-generated comment, prefixed with "##", e.g., ## unknown sender.

Logging Ajax-style Messaging in Waterken

Consider the sequence of events shown below.

Ajax-style message send

  • a remote inventory object is queried for the availability of a part
  • the inventory object reports true to teller, a callback object


The eventual send to the inventory object has two log entries: a Sent and its corresponding Got.

    "class" : [ "org.ref_send.log.Sent", "org.ref_send.log.Event" ],
    "anchor" : {
      "number" : 2,
      "turn" : {
        "loop" : "http://localhost:8080/-/buyer/",
        "number" : 3
      }
    },
    "message" : "qvet6lrs4zsfpv-2-0",
    "timestamp" : 1275338022120,
    "trace" : {
      "calls" : [ {
          "name" : "Main.Buy.fulfill",
          "source" : "org/waterken/simple_purchase_ajax/Main.java",
          "span" : [ [ 68 ] ]
        }, {
          "name" : "Main.Buy.fulfill",
          "source" : "org/waterken/simple_purchase_ajax/Main.java",
          "span" : [ [ 48 ] ]
        } ]
    }
    "class" : [ "org.ref_send.log.Got", "org.ref_send.log.Event" ],
    "anchor" : {
      "number" : 1,
      "turn" : {
        "loop" : "http://localhost:8080/-/buyer/product/",
        "number" : 2
      }
    },
    "message" : "qvet6lrs4zsfpv-2-0",
    "timestamp" : 1275338022291,
    "trace" : {
      "calls" : [ {
          "name" : "InventoryMaker.InventoryX.partInStock",
          "source" : "org/waterken/simple_purchase_ajax/InventoryMaker.java"
        } ]
    }
  • In the Sent trace record:
    • anchor uniquely identifies the origin of this message send as the 3rd messaging event from the buyer vat, turn 3.
    • message is a generated string which uniquely identifies a message.
    • trace is the stack capture at the point of the message send.

(Note: The loop field identifies the vat by URI. By convention, Causeway picks up the part following "/-/", in this case buyer, for a short display name.)

(Note: The timestamp field is optional. Currently, Causeway ignores it, so it's not shown in the remaining trace records.)

The corresponding Got has a matching message. The message delivery in the product vat starts a new turn, turn 2. Being at the top of a new turn, there is limited stack capture and getting a source span through Java reflection, is not practical.


Reporting true to teller has two log entries: a Sent and its corresponding Got.

    "class" : [ "org.ref_send.log.Sent", "org.ref_send.log.Event" ],
    "anchor" : {
      "number" : 2,
      "turn" : {
        "loop" : "http://localhost:8080/-/buyer/product/",
        "number" : 2
      }
    },
    "message" : "4qjohg533s6cjn-1-0",
    "trace" : {
      "calls" : [ {
          "name" : "InventoryMaker.InventoryX.partInStock",
          "source" : "org/waterken/simple_purchase_ajax/InventoryMaker.java",
          "span" : [ [ 19 ] ]
        } ]
    }
    "class" : [ "org.ref_send.log.Got", "org.ref_send.log.Event" ],
    "anchor" : {
      "number" : 1,
      "turn" : {
        "loop" : "http://localhost:8080/-/buyer/",
        "number" : 10
      }
    },
    "message" : "4qjohg533s6cjn-1-0",
    "trace" : {
      "calls" : [ {
          "name" : "AsyncAnd.run",
          "source" : "org/waterken/simple_purchase_ajax/AsyncAnd.java"
        } ]
    }

The reply to the query is the 2nd messaging event from the product vat, turn 2.

The corresponding Got has a matching message. The message delivery in the buyer vat starts a new turn, turn 10.

Logging Promise-based Messaging in Waterken

Our example program implements a promise-based distributed procedure for handling new purchase orders. Before an order is placed, certain conditions must be met: the item is in stock and available, the customer's account is in good standing, and the delivery options are up to date.

An object residing in the "buyer" vat has remote references to objects residing in the "product" and "accounts" vats. The buyer queries the remote objects with asynchronous (non-blocking) message sends. A promise is a placeholder for the answer to a query; when the answer becomes available the promise resolves to that value.

The code snippet below shows the 3 queries being fired off. The order of the incoming answers cannot be known. All 3 answers must be examined before the order is placed.

Collecting the answers is handled by an AsyncAnd object. The run method returns a promise for the result. By registering a when-block on the resolution of that promise, the invocation of checkAnswers is synchronized with the completion of the collection of the answers.


The resulting process-order view and message-order view are shown below.

Simple process-order view and message-order view

Personal tools
more tools