Giter VIP home page Giter VIP logo

penfold's Introduction

Penfold

Build Status

Penfold is responsible for managing queues of tasks. A task contains a payload of any valid JSON.

The primary purposes that penfold was built for:

  • messaging
  • job scheduling

Penfold is deployed as a standalone server, or mulitple standalone servers for a clustered environment.

Penfold is spoken to via a Restful API, based on the media type HAL+JSON.

Quick start

Installation and configuration

Prerequisites:

Download the latest penfold JAR file here.

Create a new empty database on your Postgres database server

Create a configuration file named "penfold.conf", and populate with:

penfold {

  publicUrl = "http://localhost:8080"

  httpPort = 8080
  
  authentication {
    username = usr
    password = pswd
  }

  database {
    url = "jdbc:postgresql://<HOST:<PORT>/<NAME_OF_EMPTY_DATABASE>"
    username = <USERNAME>
    password = <PASSWORD>
  }
}

Start penfold

java -Dconfig.file=<CONFIG_FILE_PATH>/penfold.conf -jar penfold.jar

Check if penfold server is running ok

GET: /healthcheck  HTTP 1.1

If penfold is healthy, then expect to receive a response with a 200 HTTP status code

Quick play with API

A task has a status:

  • waiting - task has been scheduled in the future and is waiting to become ready in its assigned queue
  • ready - task is available for starting
  • started - the task has been started
  • cancelled - the task has been cancelled
  • closed - the task has been closed

You can view all tasks by queue and status. For the purpose of this tutorial we will use a queue named "greenback".

GET: /queues/greenback/waiting  HTTP 1.1
GET: /queues/greenback/ready  HTTP 1.1
GET: /queues/greenback/started  HTTP 1.1
GET: /queues/greenback/cancelled  HTTP 1.1
GET: /queues/greenback/closed  HTTP 1.1

At this point, each of the above requests should not respond with any tasks.

Lets create a new task. Post the following data, replacing the "triggerDate" with a date a few minutes into the future:

POST: /tasks  HTTP 1.1

Content-Type: application/json;domain-command=CreateFutureTask
    
{
    "queue": "greenback",
    "triggerDate": "yyyy-MM-dd HH:mm:ss",
    "payload": {
        "customer": { 
            "id": 1,
            "name" : "bob",
            "email": "[email protected]"
        }
    }
}

You should see a response similar to below. The response lists the attributes of your newly created task, including an auto generated unique task ID. Notice, at this point, the "status" of the task is "waiting".

The links section of the response lists what actions and views are available for this task:

  • self - link to this task resource
  • UpdateTaskPayload - link where requests should be sent to make changes to the task payload (POST)
  • CloseTask - link where requests should be sent to close the task (POST)
201 Created
Content-Type: application/hal+json

{
    "_links": {
        "self": {
            "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02"
        },
        "CloseTask": {
            "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02/1"
        },
        "UpdateTaskPayload": {
            "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02/1"
        }
    },
    "id": "25cfd0f7-2266-4d6f-9a33-997fec57ed02",
    "payload": {
        "customer": {
            "id": 1,
            "name": "bob",
            "email": "[email protected]"
        }
    },
    "queue": "greenback",
    "status": "waiting",
    "triggerDate": "2014-07-11 16:05:00",
    "version": 1
}

Like before, send a GET request to view your task in the queue with "waiting" status.

GET: /queues/greenback/waiting  HTTP 1.1

Send another request after your task's "triggerDate" has passed to view the task as being ready.

GET: /queues/greenback/ready  HTTP 1.1

When your task is "ready", then you should see a response similar to below.

{
    "_links": {
        "self": {
            "href": "http://localhost:8080/queues/greenback/ready"
        }
    },
    "id": "greenback",
    "_embedded": {
        "tasks": [
          {
            "_links": {
                "self": {
                    "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02"
                },
                "CloseTask": {
                    "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02/2"
                },
                "StartTask": {
                    "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02/2"
                },
                "UpdateTaskPayload": {
                    "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02/2"
                }
            },
            "id": "25cfd0f7-2266-4d6f-9a33-997fec57ed02",
            "payload": {
                "customer": {
                    "id": 1,
                    "name": "bob",
                    "email": "[email protected]"
                }
            },
            "queue": "greenback",
            "status": "ready",
            "triggerDate": "2014-07-11 16:05:00",
            "version": 2
          }
        ]
    }
}

Notice the new available action link "StartTask". A task can only be started when it's "ready".

Lets start the task by sending a POST to the action link. For any task command (such as creating or starting a task), the Content-Type header MUST always include the command type (the command type is stored as the action link relation name). In this example, since a "StartTask" command has no mandatory properties the command represented in the body of the request is an empty JSON object.

POST: /tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02/2  HTTP 1.1

Content-Type: application/json;domain-command=StartTask

{}

The task has now been started, you will notice in the POST response that the task's status has changed to "started".

{
    "_links": {
        "self": {
            "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02"
        },
        "CloseTask": {
            "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02/3"
        },
        "UpdateTaskPayload": {
            "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02/3"
        }
    },
    "id": "25cfd0f7-2266-4d6f-9a33-997fec57ed02",
    "payload": {
        "customer": {
            "id": 1,
            "name": "bob",
            "email": "[email protected]"
        }
    },
    "queue": "greenback",
    "status": "started",
    "triggerDate": "2014-07-11 16:05:00",
    "version": 3
}

Finally, assuming we've done whatever we wanted to do to the task, lets tell Penfold we're done with it and close it (see "CloseTask" action link). Notice the updated Content-Type header in the request below.

POST: /tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02/3  HTTP 1.1

Content-Type: application/json;domain-command=CloseTask
    
{}

The task should now be closed.

{
    "_links": {
        "self": {
            "href": "http://localhost:8080/tasks/25cfd0f7-2266-4d6f-9a33-997fec57ed02"
        }
    },
    "id": "25cfd0f7-2266-4d6f-9a33-997fec57ed02",
    "payload": {
        "customer": {
            "id": 1,
            "name": "bob",
            "email": "[email protected]"
        }
    },
    "queue": "greenback",
    "status": "closed",
    "triggerDate": "2014-07-11 16:05:00",
    "version": 4
}

Further documentation

TODO: create these documents

  • configuration
  • logging
  • api
  • queue ordering
  • optimistic locking
  • search
  • scheduling future tasks
  • archiving tasks
  • authentication

penfold's People

Contributors

huwtl avatar

Stargazers

 avatar Derek D Owens avatar Jim Schubert avatar

Watchers

 avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.