Link Search Menu Expand Document

Extensions

Extensions are user-provided plugins, hooks, and factories. Extensions allow you to extend and modify how core parts of Spin Cycle work without changing the core code. As an open source project, Spin Cycle cannot include all possible solutions out of the box. Auth, for example, is user-specific. The auth plugin lets you tailor Spin Cycle auth for your security.

The app packages define and document all the extensions:

Start Sequence

Using any extension requires a custom build of Spin Cycle, which is described in the next section. But first, it is helpful to understand how Spin Cycle is started because after defining your extensions, your code needs to start Spin Cycle. The default start sequences are request-manager/bin/main.go and job-runner/bin/main.go. The start sequence is five steps which must be performed in order.

1. App context

The first step is creating an app context: app.Defaults(). This returns a default app context with default, built-in functions for all extensions. For example, the default auth plugin allows all callers. You should always begin with the defaults. Since main.go does not modify anything, the app context is not assigned to a variable. However, to define extensions, assign the app context to a variable: appCtx := app.Defaults().

2. Define extensions

Extensions are defined in the app context, like:

type authPlugin struct{}

appCtx.Plugins.Auth = authPlugin{}

That defines an authPlugin{} object as the auth plugin, presuming it implements auth.Plugin.

3. Create server

Create a new server object with the app context: s := server.NewServer(appCtx). This will be either a request-manager/server or job-runner/server.

4. Boot server

Boot the server: err := s.Boot(). Booting makes the server (RM or JR) ready to run. This is when most validation happens. Error are fatal; do not run the server on error.

5. Run server

The final step is running the server: s.Run(true). This blocks until the server is stopped. After calling Run(), the API is listening on the configured address.

Building

Since extensions require defining custom values in the app context (step 2), your code must import open-source Spin Cycle. Then you build your code, which builds Spin Cycle indirectly. Furthermore, if you extend and custom build one part of Spin Cycle, you should custom build the other parts. For example, if you define an auth plugin for the Request Manager, you should also custom build the Job Runner and spinc to ensure all parts originate from the same code base.

If your repo is mycorp.local/spincycle, it would contain:

job-runner/
  main.go
jobs/
  <jobs repo>
request-manager/
  main.go
spinc/
  main.go
vendor/
  github.com/
    square/
      spincycle/
        ...

Open-source Spin Cycle is a vendor package: vendor/github.com/square/spincycle. The main.go files contain your extensions, and you build the binaries from these instead of the open-source files.

Like a normal build, your jobs/ repo is needed, but the symlink is different:

$ rm -f vendor/github.com/square/spincycle/jobs
$ ln -s $PWD/jobs vendor/github.com/square/spincycle/jobs

The jobs/ dir in the open-source vendor copy needs to be a symlink that points to the jobs/ dir in your repo.

When you update the Spin Cycle vendor dep (vendor/github.com/square/spincycle), be sure to re-link the jobs directory to your jobs repo.