DEV Community

Paul Chin Jr.
Paul Chin Jr.

Posted on

Serverless Background Tasks with OpenJS Architect - Part 1

Background tasks are a common workload and perfect for serverless environments. They reinforce event-driven architecture and allow you to perform asynchronous work across a distributed system. These functions are well suited for processes that don't require an immediate response or are too resource-intensive for a single function.

OpenJS Architect, https://arc.codes, has three main primitives of background functions:

  • @events - A pub/sub service that uses AWS SNS.
  • @scheduled - Cron functions that are invoked at a specific rate with Cloudwatch Events.
  • @queues - A distributed message queue that uses AWS SQS.

Each type of function enables a reliable way for Lambda functions to call one another while also remaining stateless. This allows your distributed system to process data before it has to be committed to a persistent store. Imagine background tasks as more memory for your main functions to do more work that it doesn't have to deal with right away.

@events example

@events give your application a pub/sub message bus with AWS Simple Notification Service(SNS). In this tutorial, we will create an event topic, POST JSON data to invoke a subscribed Lambda function. Any @event function subscribed to the named topic will catch the event object, at least once. The event functions are also good for creating a one-to-many pattern. The same original event object can be sent to any number of functions.

Let's start with a fresh project and install dependencies.

npm init @architect ./arc-event-app
cd arc-event-app
npm install @architect/functions
Enter fullscreen mode Exit fullscreen mode

Open up your arc.app file and add the @event pragma along with a POST route.

# app.arc
@app
arc-event-app

@http
get /
post /yolo

@events
yolo
Enter fullscreen mode Exit fullscreen mode

Run the command arc-init to scaffold the functions that are declared in the app.arc file.

Now we can write our get-index handler. This function handler sends an HTML form to the client and allows them to make a POST request to the /yolo endpoint.

// src/http/get-index/index.js
  exports.handler = async function http() {

    let form = 
    `<form action=/yolo method=post>
      <button>YOLO</button>
    </form>`

    let html = `<!doctype html><html><body>${ form }</body></html>`

    return { 
      statusCode: 200, 
      headers: { 'content-type': 'text/html' },
      body: html
    }
  }
Enter fullscreen mode Exit fullscreen mode

Next, we're going to create a new event function in /src/events/yolo. This function is automatically subscribed to the topic created from the app.arc file and will receive a JSON payload published to the event name.

// src/events/yolo/index.js
let arc = require('@architect/functions')

async function yoloEvent(event) {
  console.log('got event', JSON.stringify(event, null, 2))
  return true
}

exports.handler = arc.events.subscribe(yoloEvent)
Enter fullscreen mode Exit fullscreen mode

The final step is creating a POST endpoint for the client to send JSON data. Good thing we can make another Lambda function, and the @architect/functions library will handle publishing and service discovery of the SNS topic.

After the library is installed we can now use it for a clean method to interact with the SNS topic. The function accepts a JSON payload with two keys: name and payload.

// src/http/post-yolo/index.js
let arc = require('@architect/functions')

async function yolo() {
  await arc.events.publish({
    // the name of the event
    name: 'yolo', 
    // the JSON payload you want to send
    payload: { 
      message: 'swag',
      timestamp: new Date(Date.now()).toISOString()
    }
  })
  return { location: '/' } 
}

exports.handler = arc.http.async(yolo)
Enter fullscreen mode Exit fullscreen mode

Test it locally by running npm start in your terminal from the project root. Architect's Sandbox environment will emulate the same behavior once your project is deployed.

Navigate to http://localhost:3333 and click the "YOLO" button and watch your terminal for the output. You should see Sandbox output the @event object and log the output of your yolo event function.

Stay tuned

In the next section we'll look at @scheduled events!

Top comments (3)

Collapse
 
snelgrove profile image
snelgrove

Nice tutorial. I agreee that events would be great for a one-to-many pattern, but I can't work out how arc lets you do that. /src/events/yolo defines one lambda function that is subscribed to yolo, but the event is derived from the path. How would you create a second function subscribed to the yolo event?

Collapse
 
pchinjr profile image
Paul Chin Jr.

You would still keep a single event mapped to one event function, but in the POST lambda you could publish to multiple event functions. For example, a single POST request would publish in parallel to two different event topics like a newsletter signup service and saving their information to a database. I hope that makes sense.

Collapse
 
snelgrove profile image
snelgrove

That makes sense. I was thinking along the lines of a more general "new-user" event, with two subscribers "newsletter signup" and "save to database".