Skip to content

Distributed Bucket4J implementation for Datomic Database

License

Notifications You must be signed in to change notification settings

fr33m0nk/clj-bucket4j-datomic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fr33m0nk/clj-bucket4j-datomic Clojars Project

Distributed Bucket4J implementation for Datomic Database
Note: this library uses Clojure wrapper for Bucket4J, clj-bucket4j

How to find this library?

Add the following to your project dependencies:

  • CLI/deps.edn dependency information
net.clojars.fr33m0nk/clj-bucket4j-datomic {:mvn/version "0.1.2"}
  • Leningen/Boot
[net.clojars.fr33m0nk/clj-bucket4j-datomic "0.1.2"]
  • Maven
<dependency>
  <groupId>net.clojars.fr33m0nk</groupId>
  <artifactId>clj-bucket4j-datomic</artifactId>
  <version>0.1.2</version>
</dependency>
  • Gradle
implementation("net.clojars.fr33m0nk:clj-bucket4j-datomic:0.1.2")

Usage

Add Datomic peer dependency in you project if not present.

Prior to using below functions, it is necessary to execute these Datomic migrations

All functions are available through the fr33m0nk.clj-bucket4j-datomic namespace

Important Functions:
Name Description
fr33m0nk.clj-bucket4j-datomic/->datomic-proxy-manager Returns Distributed Bucket4J Proxy Manager for Datomic
fr33m0nk.clj-bucket4j-datomic/add-distributed-bucket Adds a distributed bucket to Datomic. NOOP if bucket already exists.
Returns the instance of bucket
fr33m0nk.clj-bucket4j-datomic/remove-distributed-bucket Removes a distributed bucket.
Permanent removal is determined by the RecoveryStrategy chosen while creating the bucket.
Default strategy is to always RestoreOnDelete

Example:

Suppose you need to have a fresh exchange rate between dollars and euros. To get the rate you continuously poll the third-party provider, and by contract with the provider you should poll not often than 100 times per 1 minute, else provider will block your IP:

(require '[datomic.api :as d] '[fr33m0nk.clj-bucket4j :as b4j] '[fr33m0nk.datomic-schema :refer [b4j-schema]] '[fr33m0nk.clj-bucket4j-datomic :as b4j-datomic])
(import '(io.github.bucket4j.distributed.proxy ClientSideConfig))

(def datomic-conn (return-datomic-connection))

;; Execute Datomic migrations for supporting Distributed Bucket4J
@(d/transact datomic-conn b4j-schema)

;; Instance of datomic-proxy-manager
;; For most cases `(ClientSideConfig/getDefault)` is enough
;; Look into documentation of ClientSideConfig to figure right scenarios to customize it
(def datomic-proxy-manager (b4j-datomic/->datomic-proxy-manager datomic-conn (ClientSideConfig/getDefault)))

;; Bucket configuration allowing 100 hits in 60000 ms (1 minute)
(def bucket-configuration (-> (b4j/bucket-configuration-builder)
                              (b4j/add-limit (b4j/simple-bandwidth 100 60000))
                              (b4j/build)))

;; Adds a distributed bucket to Datomic
(def distributed-bucket (b4j-datomic/add-distributed-bucket proxy-manager "test-bucket-1" bucket-configuration))

(def exchange-rates (atom 0.0))

;; do polling in infinite loop
(while true
  ;; Consume a token from the token bucket.
  ;; Depending on the availability of Token, `b4j/try-consume` returns true or false.
  (when (b4j/try-consume distributed-bucket 1)
    (swap! exchange-rate #(identity %2) (poll-exchange-rate))))

More detailed usages of above functions and more can be found in tests.

License

Copyright © 2023 Prashant Sinha

Distributed under the MIT License.