Anatomy of a Riff Function
UPDATE: Much has changed with riff the past year, including a complete ground-up rearchitecture on top of Knative. I’ve decided to leave this post up for posterity, but be sure to check out https://projectriff.io/ for current documentation on Project riff!
If you’ve recently started getting familiar with Riff, you’ve probably also begun looking into what goes into creating a Riff function. Taking a look at some of the available examples (say, a simple bash function), you’ll notice along side the actual code of the function are some additional files. Thanks to the newest version of the Riff client, these can all be generated with a single command, but it’s still incredibly useful to understand what goes into these files.
NOTE: At the time of writing, Riff is on release 0.0.4. Be sure to check out the Project Riff website as well as follow Riff on Twitter for the latest changes.
Let’s dig through what’s generated in the scenario of the simple bash function linked above. The only bit I wrote (aside from the README) is the 2-line function. Everything else was generated with the Riff CLI:
> riff create shell --name echo-shellInitializing /Users/brian/code/riff-demos/functions/echo/shell/echo-shell-topics.yaml
Initializing /Users/brian/code/riff-demos/functions/echo/shell/echo-shell-function.yaml
Initializing /Users/brian/code/riff-demos/functions/echo/shell/Dockerfile
Building image ...[...]Applying resources in .function "echo-shell" created
topic "echo-shell" created
We can see from the first few lines that three files are generated:
- echo-shell-topics.yaml
- echo-shell-function.yaml
- Dockerfile
Dockerfile
The Dockerfile has a few responsibilities:
- Define which invoker to use
- What files to include in your container image and where to store them
- How to invoke the function
FROM projectriff/shell-function-invoker:latest
ARG FUNCTION_URI="/echo-shell.sh"
ADD echo-shell.sh /
ENV FUNCTION_URI $FUNCTION_URI
There’s not much surprising here. Using Project Riff’s shell-function-invoker
image as a base, we simply add our function to it. The one part that is a bit special is the FUNCTION_URL
environment variable, which is used by the shell-function-invoker later to run our function.
In the case of a Java function, for example, this may also include the class that contains our function as well, as seen below where we invoke the Echo
class in the functions
package:
FROM projectriff/java-function-invoker:latest
ARG FUNCTION_JAR=/functions/echo-1.0.0.jar
ARG FUNCTION_CLASS=functions.Echo
ADD target/echo-1.0.0.jar $FUNCTION_JAR
ENV FUNCTION_URI file://${FUNCTION_JAR}?handler=${FUNCTION_CLASS}
echo-shell-topics.yaml
The topics file is also pretty straightforward, especially in this demo:
apiVersion : projectriff.io/v1
kind: Topic
metadata:
name: echo-shell
spec:
partitions: 3
We’ve defined a new topic that functions can listen and publish to named “echo-shell”, and allowed for a maximum of three partitions. That is, as requests come into this topic, we’ll allow up to 3 simultaneous instances of our function to be handling messages published to this topic, depending on the load. Riff will take care of the logistics of when to scale up the number of pods for our function, and should we need to allow for a larger load, we can simply crank this number up!
echo-shell-function.yaml
Finally, we have our function definition. Let’s take a look at it first:
apiVersion: projectriff.io/v1
kind: Function
metadata:
name: echo-shell
spec:
protocol: grpc
input: echo-shell
container:
image: brian/echo-shell:0.0.1
Aside from the name
entry, being the name we wish to give to our function, let’s step through them one by one:
protocol
: This defines what protocol to use for communication between the sidecar (responsible for taking input from the input topic and providing it to the function invoker) and function invoker (Responsible for, well, invoking our function). As of writing, the supported options are grpc
, http
and stdio
, however be sure to keep an eye on future Riff releases as this is a rapidly evolving feature. The gRPC support is currently the recommended protocol and all function invokers published by the Riff team support it.
input
: This is the topic that the function should listen to for events. In our case, this will be the topic we defined in our echo-shell-topics.yaml
file named echo-shell
.
image
: Finally, the Docker image that we built for our image. This will depend a bit on your deployment situation, however. For example, in our Minikube tutorial we used a local image cache, in which case the value that’s generated with the riff create
command will work without issue. In our GKE tutorial however, we used GCR to host our image and, as a result, had to update our image path.
There is also the option of sending the output of one function to another topic, not shown. In this case, there’s an additional entry we can place alongside input
called, unsurprisingly, output
. For more on chaining functions together, check out this demo on GitHub.
What’s Next
It’s an important to point out that as Riff is currently tagged as v0.0.4, the content here is subject to change. Be sure to follow Project Riff on Twitter as the team is hard at work and constantly putting out updates.
If you’re looking for some examples and demos, Check out the Riff samples as well as the demos written for the tutorial videos. Jump in and give Riff a shot!