Getting Started

Installing

Build Grackle from sources:

# Checkout source code
$ git clone git@github.com:evrblk/grackle.git
$ cd grackle

# Build
$ make grackle

Running

Grackle can operate in a clustered mode (with replication and sharding), or it can run in a single-process nonclustered mode (full state on disk, no replication, no sharding).

Nonclustered mode

$ ./grackle run nonclustered --port=8000 --data-dir=./data

Clustered mode

There are 3 components:

  • gateway stateless API gateway
  • node stateful node with data persisted on the disk
  • worker stateless async worker

Running in the clustered mode requires Monstera cluster config file. To generate a simple config run:

$ go tool github.com/evrblk/monstera/cmd/monstera config init \
  --node=localhost:7001 \
  --node=localhost:7002 \
  --node=localhost:7003 \
  --output=./cluster_config.json

$ go tool github.com/evrblk/monstera/cmd/monstera config add-application \
  --config=./cluster_config.json \
  --name=GrackleLocks \
  --implementation=GrackleLocks \
  --shards-count=16
  
$ go tool github.com/evrblk/monstera/cmd/monstera config add-application \
  --config=./cluster_config.json \
  --name=GrackleSemaphores \
  --implementation=GrackleSemaphores \
  --shards-count=16
  
$ go tool github.com/evrblk/monstera/cmd/monstera config add-application \
  --config=./cluster_config.json \
  --name=GrackleWaitGroups \
  --implementation=GrackleWaitGroups \
  --shards-count=16
  
$ go tool github.com/evrblk/monstera/cmd/monstera config add-application \
  --config=./cluster_config.json \
  --name=GrackleNamespaces \
  --implementation=GrackleNamespaces \
  --shards-count=8

This will create ./cluster_config.json file with 3 nodes and 4 sharded application cores that are parts of Grackle. Take a look inside to see how actually simple it is.

Then run all components:

$ ./grackle run node --node-address=localhost:7001 --data-dir=./data/node1 --monstera-config=./cluster_config.json
$ ./grackle run node --node-address=localhost:7002 --data-dir=./data/node2 --monstera-config=./cluster_config.json
$ ./grackle run node --node-address=localhost:7003 --data-dir=./data/node3 --monstera-config=./cluster_config.json

$ ./grackle run worker --monstera-config=./cluster_config.json

$ ./grackle run gateway --port=8000 --monstera-config=./cluster_config.json

Using

Use with evrblk CLI tool from github.com/evrblk/evrblk-cli.

Example:

$ evrblk grackle-preview list-namespaces --endpoint=localhost:8000
{}

$ echo '{"name": "name1"}' | evrblk grackle-preview create-namespace --endpoint=localhost:8000
{
  "namespace":  {
    "name":  "name1",
    "createdAt":  "1760464456161083000",
    "updatedAt":  "1760464456161083000"
  }
}

$ echo '{"namespace_name": "name1"}' | evrblk grackle-preview list-locks --endpoint=localhost:8000
{}

Or use with official Everblack SDKs:

Example in Go:

import (
	"time"
    evrblk "github.com/evrblk/evrblk-go"
    grackle "github.com/evrblk/evrblk-go/grackle/preview"
)

grackleClient := grackle.NewGrackleGrpcClient("localhost:8000", evrblk.NewNoOpSigner())

acquireLockResp, err := grackleClient.AcquireLock(context.Background(), &grackle.AcquireLockRequest{
    NamespaceName: "my_namespace"
	LockName: "lock1",
	WriteLock: true,
    ProcessId: "process1",
	ExpiresAt: time.Now().Add(5 * time.Minute).UnixNano()
})