Skip to content

Hypermedia workflows redux

Erik Mogensen edited this page Sep 9, 2015 · 7 revisions

Hypermedia workflows redux

Hack day proposal

Take the hypermedia "work order" media type built for the 2013 hack day, and build clients that understand how to "make a move" and perhaps "present a board". "Work" here means making an actual chess move.

The goal is to produce a "workflow-like" system which can play a distributed game of chess.

  • The "Worker" would be given (using the "work needed" media type from 2013).

    • a board with (chess) pieces on it
    • a number of legal moves
    • hypermedia controls to provide the legal move
  • The server would

    • provide various URLs where chess playing workers may seek moves to be made.
    • provide "current board" and "legal moves" to the workers
    • accept the moves made by these workers.

Preparations

Before the event, we need to define the worker media type (already done), along with the language of the board and legal moves (should happen on this page).

For the board, I suggest a FEN String, as it's plain text, easy to understand and helpful when debugging a board. There are also visualizations of FEN strings available that could be used by participants the hack day, tools to create test data, there are libraries for checking validity, checkmates, loading/saving FEN, getting a list of legal moves, making moves etc.

For the legal moves, I'm a fan of PGN (i.e. the subset of PGN which identifies a move. So e.g. Nxf7 would identify a Knight taking on f7. The list of legal moves could be as simple as a whitespace-separated String of these, and the chosen move would be one of those "words".

Static files should be made to serve as test data for clients, using hypermedia controls to guide them through a fictional game of chess when served using a simple web server.

A "pick the first legal move" client should be built to serve as a tester for servers.

The hack day itself

At the event, some people may already have working chess playing clients or servers, and will wire these together.

Others would build these at the venue, and advertise their server on a github page or on a whiteboard.

Adventurous souls might use <a hrefs> from the github page to start off a random game :)

Supervisor

In addition to the above, where the server knows the rules of chess, a couple of more components could be commissioned at the hack day, in order to produce a server that doesn't know chess either, by adding an "supervisor" to the mix:

  • The ignorant server would (in addition to what the server does):

    • when a worker makes "a move" provide a "feed" of decisions to be made to another type of worker, called the supervisor
    • provide the "current board", "chosen move" to the supervisor
    • provide hypermedia controls for the supervisor to make its decision on how to proceed.
  • The chess supervisor client would:

    • ask the ignorant server for the next "ruling"
    • inspect the board, update it, compile a list of new legal moves,
    • use hypermedia controls provided by the server to provide its results.

Preparations

Before the event, we need to define the supervisor media type(s) (see below).

Static files should be made to serve as test data for supervisor clients, using hypermedia controls to guide them through various chess games when served using a simple web server.

A "compile a list of a couple of random moves" supervisor should be built to serve as a tester for servers.

The hack day itself

Some participants would make supervisor (clients), while others would make servers that could talk to both supervisor and chess playing clients.

Wrap up

If the full proposal is chosen the end result would be:

  • chess playing clients of various types that all can select moves (at random, using AI, asking a human)
  • supervisors that decide if a move is good, the current board, and the list of legal next moves
  • a few servers that service the needs of chess playing clients only
  • a few servers that service the needs of both chess playing clients and supervisors

In the end we should be able to play a good game of chess. Maybe someone will write a server or supervisor that (when a move has been chosen) uses (creates work for) the Text-to-Speech worker built two years ago to read the moves out loud as they are accepted by the supervisor, perhaps with witty commentary.

Details on the "Supervisor"

A supervisor process makes requests to a feed of some sort of documents that contain "requests for supervision, and hypermedia controls in the response typically guide the client to send a document of type "decisions" back to the server if all goes well.

Request for supervision

Instance documents of this type are typically sent from a server to a supervisory client. The sender has some workflow that is executing, and something has prompted it to ask the recipient to make a decision on what to do.

To make things easy let's use a HAL based document, for (somewhat) easier tooling and out-of-the-box understanding at a low level

Here's an example of a supervisor that is being told that we're at a pristine board, and the first move was "e4", with the URL to where the server wants the supervisor's decisions to be sent. The "data" sent comes from a worker that knows how to make a move.

GET /chess-game/23j89nuklyedsio/

200 OK
Content-Type: application/vnd.mogsie.workflow.events+json

{
  "current-state" : "tag:chess.mogsie.com,2001:game-in-progress",
  "data" : {
    "board" : "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
  }
  "recent-events" : [
    { "type" : "work-completed",
      "name": "make-a-move",
      "data": { "move" : "e4" }
    },
  ],
  "_links": {
    "make-decisions" : { "href" : "./make-decisions" },
  }
}
  • current-state — a URI that identifies the current state of the workflow execution in question. In this case we're in a chess game.
  • data — Some data that was previously tucked away by earlier interactions with supervisors, in this case the current chess board.
  • recent-events — An array of objects that each describe something that has recently happened in this game
    • type — string: always "work-completed", indicating that some work that was previously started was completed (“data” contains the result of the worker’s work).
    • name — The name previously given to the work that completed, to disambiguate between different work completing.
    • data — The actual output of the worker (if any), in our case the chosen move.

Links in the document are as follows:

  • make-decisions — A writable hypermedia control that the recipient (supervisor) may invoke when it is ready to do some supervising. When doing so, a POST request is sent to this URI, with content of type application/vnd.mogsie.workflow.decisions+json, containing the decisions.

The structure of the document is as it is in order to be able to evolve into a larger media type with more options that cater for timeouts, aborting workers, external signals and so on.

Making Decisions (application/vnd.mogsie.workflow.decisions+json)

Instances of this media type are typically sent when invoking the make-decisions hypermedia control. Instances of this media type describes

  • The new resting state (identified by a URI).
  • Any work that might need to happen (in our case we typically want someone to make a move).

Here is a simple example, the supervisor instructing a "chess playing worker" to make a move, telling the worker the current board layout and the list of legal moves (required inputs to that worker).

POST /chess-game/23j89nuklyedsio/make-decisions
Content-Type: application/vnd.mogsie.workflow.decisions+json

{
  "current-state" : "tag:chess.mogsie.com,2001:game-in-progress",
  "data" : {
     "board" : "rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR b KQkq - 0 1"
  },
  "decisions": [
    { "type" : "schedule-work",
      "name" : "make-a-move",
      "work" : 
      { "type" : "http://mogsie.com/static/workflow/make-chess-move",
        "input" : {
          "board" : "rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR b KQkq - 0 1",
          "legal-moves" : [ "a5", "a6", "b5", "b6", "c5", "c6" .... ]
        }
      }
    }
  ]
}

This decision asks the server to find a worker that can make a (new) chess move. The local name given to the work is "make-a-move" which would be used later when that completes, to differentiate it from other types of work.

The fields of the application/vnd.mogsie.workflow.decisions+json document:

  • current-state — A URI, identifying the new resting state
  • data — new data that should be "kept", for the next supervisor
  • decisions — an array containing decisions
    • type — A string, identifying the type of decision
      • schedule-work: Indicates that the recipient should try to get some work done.
    • name — A name given to this piece of work, so that it may be recognised when it's done
    • work — Describes the work that needs to be done, a Work-order.
      • type: The type of work (a URI)
      • input: An object describing the input required by the type of work
Clone this wiki locally