• This repository has been archived on 31/Mar/2021
  • Stars
    star
    196
  • Rank 191,541 (Top 4 %)
  • Language
    Kotlin
  • License
    Apache License 2.0
  • Created almost 6 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

BigBen - a generic, multi-tenant, time-based event scheduler and cron scheduling framework

NOTICE:

This repository has been archived and is not supported.

No Maintenance Intended


NOTICE: SUPPORT FOR THIS PROJECT HAS ENDED

This projected was owned and maintained by Walmart. This project has reached its end of life and Walmart no longer supports this project.

We will no longer be monitoring the issues for this project or reviewing pull requests. You are free to continue using this project under the license terms or forks of this project at your own risk. This project is no longer subject to Walmart's bug bounty program or other security monitoring.

Actions you can take

We recommend you take the following action:

  • Review any configuration files used for build automation and make appropriate updates to remove or replace this project
  • Notify other members of your team and/or organization of this change
  • Notify your security team to help you evaluate alternative options

Forking and transition of ownership

For security reasons, Walmart does not transfer the ownership of our primary repos on Github or other platforms to other individuals/organizations. Further, we do not transfer ownership of packages for public package management systems.

If you would like to fork this package and continue development, you should choose a new name for the project and create your own packages, build automation, etc.

Please review the licensing terms of this project, which continue to be in effect even after decommission.

BigBen

BigBen is a generic, multi-tenant, time-based event scheduler and cron scheduling framework based on Cassandra and Hazelcast

It has following features:

  • Distributed - BigBen uses a distributed design and can be deployed on 10's or 100's of machines and can be dc-local or cross-dc
  • Horizontally scalable - BigBen scales linearly with the number of machines.
  • Fault tolerant - BigBen employs a number of failure protection modes and can withstand arbitrary prolonged down times
  • Performant - BigBen can easily scale to 10,000's or even millions's of event triggers with a very small cluster of machines. It can also easily manage million's of crons running in a distributed manner
  • Highly Available - As long as a single machine is available in the cluster, BigBen will guarantee the execution of events (albeit with a lower throughput)
  • Extremely consistent - BigBen employs a single master design (the master itself is highly available with n-1 masters on standby in an n cluster machine) to ensure that no two nodes fire the same event or execute the same cron.
  • NoSql based - BigBen comes with default implementation with Cassandra but can be easily extended to support other NoSql or even RDBMS data stores
  • Auditable - BigBen keeps a track of all the events fired and crons executed with a configurable retention
  • Portable, cloud friendly - BigBen comes as application bundled as war or an embedded lib as jar, and can be deployed on any cloud, on-prem or public

Use cases

BigBen can be used for a variety of time based workloads, both single trigger based or repeating crons. Some of the use cases can be

  • Delayed execution - E.g. if a job is to be executed 30 mins from now
  • System retries - E.g. if a service A wants to call service B and service B is down at the moment, then service A can schedule an exponential backoff retry strategy with retry intervals of 1 min, 10 mins, 1 hour, 12 hours, and so on.
  • Timeout tickers - E.g. if service A sends a message to service B via Kafka and expects a response in 1 min, then it can schedule a timeout check event to be executed after 1 min
  • Polling services - E.g. if service A wants to poll service B at some frequency, it can schedule a cron to be executed at some specified frequency
  • Notification Engine - BigBen can be used to implement notification engine with scheduled deliveries, scheduled polls, etc
  • Workflow state machine - BigBen can be used to implement a distributed workflow with state suspensions, alerts and monitoring of those suspensions.

Architectural Goals

BigBen was designed to achieve the following goals:

  • Uniformly distributed storage model
    • Resilient to hot spotting due to sudden surge in traffic
  • Uniform execution load profile in the cluster
    • Ensure that all nodes have similar load profiles to minimize misfires
  • Linear Horizontal Scaling
  • Lock-free execution
    • Avoid resource contentions
  • Plugin based architecture to support variety of data bases like Cassandra, Couchbase, Solr Cloud, Redis, RDBMS, etc
  • Low maintenance, elastic scaling

Design and architecture

See the blog published at Medium for a full description of various design elements of BigBen

Events Inflow

BigBen can receive events in two modes:

  • kafka - inbound and outbound Kafka topics to consume event requests and publish event triggers
  • http - HTTP APIs to send event requests and HTTP APIs to receive event triggers.

It is strongly recommended to use kafka for better scalability

Event Inflow diagram

inflow

Request and Response channels can be mixed. For example, the event requests can be sent through HTTP APIs but the event triggers (response) can be received through a Kafka Topic.

Event processing guarantees

BigBen has a robust event processing guarantees to survive various failures. However, event-processing is not same as event-acknowledgement. BigBen works in a no-acknowledgement mode (at least for now). Once an event is triggered, it is either published to Kafka or sent through an HTTP API. Once the Kafka producer returns success, or HTTP API returns non-500 status code, the event is assumed to be processed and marked as such in the system. However, for whatever reason if the event was not processed and resulted in an error (e.g. Kafka producer timing out, or HTTP API throwing 503), then the event will be retried multiple times as per the strategies discussed below

Event misfire strategy

Multiple scenarios can cause BigBen to be not able to trigger an event on time. Such scenarios are called misfires. Some of them are:

  • BigBen's internal components are down during event trigger. E.g.

    • BigBen's data store is down and events could not be fetched
    • VMs are down
  • Kafka Producer could not publish due to loss of partitions / brokers or any other reasons

  • HTTP API returned a 500 error code

  • Any other unexpected failure

In any of these cases, the event is first retried in memory using an exponential back-off strategy.

Following parameters control the retry behavior:

  • event.processor.max.retries - how many in-memory retries will be made before declaring the event as error, default is 3
  • event.processor.initial.delay - how long in seconds the system should wait before kicking in the retry, default is 1 second
  • event.processor.backoff.multiplier - the back off multiplier factor, default is 2. E.g. the intervals would be 1 second, 2 seconds, 4 seconds.

If the event still is not processed, then the event is marked as ERROR. All the events marked ERROR are retried up to a configured limit called events.backlog.check.limit. This value can be an arbitrary amount of time, e.g. 1 day, 1 week, or even 1 year. E.g. if the the limit is set at 1 week then any event failures will be retried for 1 week after which, they will be permanently marked as ERROR and ignored. The events.backlog.check.limit can be changed at any time by changing the value in bigben.yaml file and bouncing the servers.

Event bucketing and shard size

BigBen shards events by minutes. However, since it's not known in advance how many events will be scheduled in a given minute, the buckets are further sharded by a pre defined shard size. The shard size is a design choice that needs to be made before deployment. Currently, it's not possible to change the shard size once defined.

An undersized shard value has minimal performance impact, however an oversized shard value may keep some machines idling. The default value of 1000 is good enough for most practical purposes as long as number of events to be scheduled per minute exceed 1000 x n, where n is the number of machines in the cluster. If the events to be scheduled are much less than 1000 then a smaller shard size may be chosen.

Multi shard parallel processing

Each bucket with all its shards is distributed across the cluster for execution with an algorithm that ensures a random and uniform distribution. The following diagram shows the execution flow.
shard design

Multi-tenancy

Multiple tenants can use BigBen in parallel. Each one can configure how the events will be delivered once triggered. Tenant 1 can configure the events to be delivered in kafka topic t1, where as tenant 2 can have them delivered via a specific http url. The usage of tenants will become more clearer with the below explanation of BigBen APIs

Docker support

BigBen is dockerized and image (bigben) is available on docker hub. The code also contains scripts, which start cassandra, hazelcast and app. To quickly set up the application for local dev testing, do the following steps:

  1. git clone $repo
  2. cd bigben/build/docker
  3. execute ./docker_build.sh
  4. start cassandra container by executing ./cassandra_run.sh
  5. start app by executing ./app_run.sh
  6. To run multiple app nodes export NUM_INSTANCES=3 && ./app_run.sh
  7. wait for application to start on port 8080
  8. verify that curl http://localhost:8080/ping returns 200
  9. Use ./cleanup.sh to stop and remove all BigBen related containers

Non-docker execution

BigBen can be run without docker as well. Following are the steps

  1. git clone $repo
  2. cd bigben/build/exec
  3. execute ./build.sh
  4. execute ./app_run.sh

Env properties

You can set the following environment properties

  1. APP_CONTAINER_NAME (default bigben_app)
  2. SERVER_PORT (default 8080)
  3. HZ_PORT (default 5701)
  4. NUM_INSTANCES (default 1)
  5. LOGS_DIR (default bigben/../bigben_logs)
  6. CASSANDRA_SEED_IPS (default $HOST_IP)
  7. HZ_MEMBER_IPS (default $HOST_IP)
  8. JAVA_OPTS

#How to override default config values? BigBen employs an extensive override system to allow someone to override the default properties. The order of priority is system properties > system env variables > overrides > defaults The overrides can be defined in config/overrides.yaml file. The log4j.xml can also be changed to change log behavior without recompiling binaries

How to setup Cassandra for BigBen?

Following are the steps to set up Cassandra:

  1. git clone the master branch
  2. Set up a Cassandra cluster
  3. create a keyspace bigben in Cassandra cluster with desired replication
  4. Open the file bigben-schema.cql and execute cqlsh -f bigben-schema.cql

APIs

cluster

GET /events/cluster

  • response sample (a 3 node cluster running on single machine and three different ports (5701, 5702, 5703)):
{
    "[127.0.0.1]:5702": "Master",
    "[127.0.0.1]:5701": "Slave",
    "[127.0.0.1]:5703": "Slave"
}

The node marked Master is the master node that does the scheduling.

tenant registration

A tenant can be registered by calling the following API

POST /events/tenant/register

  • payload schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "tenant": {
      "type": "string"
    },
    "type": {
      "type": "string"
    },
    "props": {
      "type": "object"
    }
  },
  "required": [
    "tenant",
    "type",
    "props"
  ]
}
  • tenant - specifies a tenant and can be any arbitrary value.

  • type - specifies the type of tenant. One of the three types can be used

    • MESSAGING - specifies that tenant wants events delivered via a messaging queue. Currently, kafka is the only supported messaging system.
    • HTTP - specifies that tenant wants events delivered via an http callback URL.
    • CUSTOM_CLASS - specifies a custom event processor implemented for custom processing of events
  • props - A bag of properties needed for each type of tenant.

  • kafka sample:

{
    "tenant": "TenantA/ProgramB/EnvC",
    "type": "MESSAGING",
    "props": {
        "topic": "some topic name",
        "bootstrap.servers": "node1:9092,node2:9092"
    }
}
  • http sample
{
     "tenant": "TenantB/ProgramB/EnvC",
     "type": "HTTP",
     "props": {
          "url": "http://someurl",
          "headers": {
            "header1": "value1",
            "header2": "value2"
          }
     }
}

fetch all tenants:

GET /events/tenants

event scheduling

POST /events/schedule

Payload - List<EventRequest>

EventRequest schema:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "eventTime": {
      "type": "string",
      "description": "An ISO-8601 formatted timestamp e.g. 2018-01-31T04:00.00Z"
    },
    "tenant": {
      "type": "string"
    },
    "payload": {
      "type": "string",
      "description": "an optional event payload, must NOT be null with deliveryOption = PAYLOAD_ONLY"
    },
    "mode": { 
      "type": "string",
      "enum": ["UPSERT", "REMOVE"],
      "default": "UPSERT",
      "description": "Use REMOVE to delete an event, UPSERT to add/update an event"
    },
    "deliveryOption": {
      "type": "string",
      "enum": ["FULL_EVENT", "PAYLOAD_ONLY"],
      "default": "FULL_EVENT",
      "description": "Use FULL_EVENT to have full event delivered via kafka/http, PAYLOAD_ONLY to have only the payload delivered"
    }
  },
  "required": [
    "id",
    "eventTime",
    "tenant"
  ]
}

find an event

GET /events/find?id=?&tenant=?

dry run

POST /events/dryrun?id=?&tenant=?

fires an event without changing its final status

cron APIs

coming up...

More Repositories

1

lacinia

GraphQL implementation in pure Clojure
Clojure
1,798
star
2

thorax

Strengthening your Backbone
JavaScript
1,324
star
3

react-ssr-optimization

React.js server-side rendering optimization with component memoization and templatization
JavaScript
821
star
4

electrode

Electrode - Application Platform on React/Node.js powering Walmart.com
446
star
5

little-loader

A lightweight, IE8+ JavaScript loader
JavaScript
371
star
6

json-to-simple-graphql-schema

Transforms JSON input into a GraphQL schema
JavaScript
279
star
7

eslint-config-defaults

A composable set of ESLint defaults
JavaScript
229
star
8

lumbar

Modular javascript build tool
JavaScript
226
star
9

datascope

Visualization of Clojure data structures using Graphviz
Clojure
206
star
10

lacinia-pedestal

Expose Lacinia GraphQL as Pedestal endpoints
Clojure
197
star
11

concord

Concord - workflow orchestration and continuous deployment management
Java
195
star
12

kubeman

The Hero that Kubernetes deserves
TypeScript
164
star
13

system-viz

Graphviz visualization of a component system
Clojure
159
star
14

react-native-orientation-listener

A react-native library for obtaining current device orientation
Java
151
star
15

thorax-seed

JavaScript
131
star
16

vizdeps

Visualize Leiningen dependencies using Graphviz
Clojure
130
star
17

mupd8

Muppet
Scala
126
star
18

active-status

Present status of mulitple 'jobs' in a command line tool, using terminal capability codes
Clojure
118
star
19

schematic

Combine configuration with building a Component system
Clojure
104
star
20

easy-fix

easy-fix: run integration tests like unit tests
JavaScript
101
star
21

dyn-edn

Dynamic properties in EDN content
Clojure
94
star
22

fruit-loops

Server-side jQuery API renderer.
JavaScript
89
star
23

generator-thorax

Thorax yeoman generator
JavaScript
87
star
24

walmart-cla

Walmart Contributor License Agreement Information
85
star
25

react-native-cropping

Cropping components for react-native
JavaScript
68
star
26

curved-carousel

An infinitely scrolling carousel with configurable curvature
JavaScript
64
star
27

walmart-api

API wrapper for the public Walmart Labs API
JavaScript
62
star
28

gozer

Open source library to parse various X12 file formats for retail/supply chain
Java
60
star
29

cookie-cutter

An opinionated micro-services framework for TypeScript
TypeScript
57
star
30

mock-server

SPA application debug proxy server
JavaScript
56
star
31

test-reporting

Tiny library to assist with reporting some context when a test fails
Clojure
53
star
32

container-query

A responsive layout helper based on the width of the container
JavaScript
52
star
33

react-native-platform-visible

A very simple component visibility switch based on Platform
JavaScript
49
star
34

eslint-config-walmart

A set of default eslint configurations, Walmart Labs style.
JavaScript
48
star
35

clojure-game-geek

Example source code for the Lacinia tutorial
Clojure
47
star
36

babel-plugin-react-cssmoduleify

Babel plugin to transform traditional React element classNames to CSS Modules
JavaScript
45
star
37

generator-release

Yeoman generator for handling Bower/NPM releases.
JavaScript
45
star
38

costanza

Frontend error tracking toolkit: Own your own domain
JavaScript
35
star
39

zFAM

z/OS-based File Access Manager
Assembly
35
star
40

nightcall

Automated Enumeration Script for Pentesting
Python
34
star
41

cond-let

A useful merge of cond and let
Clojure
30
star
42

static

JavaScript
26
star
43

bolt

[DEPRECATED] an opinionated meta task runner for components.
JavaScript
24
star
44

shared-deps

Leiningen plugin to allow sub-modules to more easily share common dependencies
Clojure
24
star
45

ridicule

Mocking everything
JavaScript
22
star
46

linearroad

Walmart version of the Linear Road streaming benchmark.
Java
22
star
47

backbone-historytracker

Backbone plugin for navigation direction tracking
JavaScript
22
star
48

zECS

z/OS-based Enterprise Cache Service
COBOL
21
star
49

pulsar

Text-based dashboard for Elixir CLIs
Elixir
20
star
50

react-native-image-progressbar

An image based progress bar
JavaScript
20
star
51

layout

A simple responsive layout helper
CSS
17
star
52

zUID

z/OS-based Unique Identifier generator
Assembly
16
star
53

showcase-template

A starter template for a showcase of React components
CSS
16
star
54

grunt-release-component

Grunt release helper for bower components
JavaScript
15
star
55

anomaly-detection-walmart

Python
14
star
56

partnerapi_sdk_dotnet

Walmart Partner API SDK for .NET
C#
14
star
57

circus

External Webpack Component Plugin
JavaScript
13
star
58

concord-website

Documentation website source code for Concord
JavaScript
13
star
59

concord-plugins

Java
12
star
60

strati-functional

A lightweight collection of functional classes used to complement core Java.
Java
12
star
61

thorax-boilerplate

A boilerplate project for Thoroax
JavaScript
11
star
62

nocktor

nocktor - your nock doctor
JavaScript
11
star
63

getting-started

How to get started with the WalmartLabs API and tooling
9
star
64

LinearGenerator

Reworked data generator for LinearRoad streaming benchmark that no longer needs mitsim or any database.
Java
9
star
65

json-patchwork

JavaScript
9
star
66

object-diff

A Go library implementing object wise diff and patch.
Go
8
star
67

small-world-graph

Graphing as in Data
C++
8
star
68

chai-shallowly

A chai assertion plugin for enzyme.
JavaScript
8
star
69

typeahead.js-legacy

typeahead.js is a fast and fully-featured autocomplete library
JavaScript
8
star
70

child-pool

child_process pool implementation
JavaScript
7
star
71

thorax-todos

JavaScript
6
star
72

hula-hoop

Server-side rendering components for Thorax + Hapi stacks.
JavaScript
6
star
73

apache-http-client

A Clojure ring compatible http interface for Apache HttpClient
Clojure
5
star
74

lumbar-loader

JavaScript
5
star
75

krabby

JavaScript
4
star
76

js-conceptualizer

JS Conceptualizer is a bit of client-side Javascript that parses out concepts, particularly proper nouns, from HTML on a web page.
JavaScript
4
star
77

babel-plugin-i18n-id-hashing

Namespace the ID of React-Intl keys
JavaScript
4
star
78

express-example

A crazy simple example of using the Walmart API with express
JavaScript
4
star
79

wml-coding-std

A module for keeping consistent JS coding standards at WML
JavaScript
3
star
80

nativedriver

native driver for UI automation
Objective-C
3
star
81

was

Go
3
star
82

thorax-rails

Ruby
3
star
83

hapi-example

A crazy simple example of using the Walmart API with hapi
JavaScript
3
star
84

lumbar-long-expires

Long expires cache buster plugin for Lumbar
JavaScript
3
star
85

component-scan

A component scanner for React
JavaScript
3
star
86

scanomatic-server

Scan-O-Matic Node Server
JavaScript
3
star
87

hadoop-openstack-swifta

hadoop-openstack-swifta
Java
3
star
88

SDJSBridge

Native/Hybrid Javascript Bridge
Objective-C
2
star
89

cordova-starter-kit

A starter kit for using Cordova and the Walmart API
JavaScript
2
star
90

priorityY

Priority Based Connected Components
Python
2
star
91

bolt-standard-flux

electrode bolt standard configs and tasks for flux architecture.
JavaScript
1
star
92

github-util

Github utility methods.
JavaScript
1
star
93

lumbar-tester

Unit testing plugin for Lumbar
JavaScript
1
star
94

apidocs

HTML
1
star
95

circus-stylus

Stylus linker for Circus components
JavaScript
1
star
96

SDUserActivity

An simplified interface for NSUserActivity for apps that want to participate in handoff.
Objective-C
1
star
97

walmartlabs.github.io

Helper to redirect to code.walmartlabs.com
HTML
1
star
98

BurpSuiteDynamicSessionTracker

BurpSuite extension for tracking and manipulating dynamic session cookies
Java
1
star
99

bolt-cli

[DEPRECATED] bolt command line interface.
JavaScript
1
star
100

phoenix-build

Common build libraries for Phoenix projects
JavaScript
1
star