Giter Site home page Giter Site logo

mjunaidi / idempotence4j Goto Github PK

View Code? Open in Web Editor NEW

This project forked from transferwise/idempotence4j

0.0 1.0 0.0 292 KB

Lightweight library for handling idempotent actions

Home Page: https://github.com/transferwise/idempotence4j

License: Other

Java 56.59% Groovy 43.31% Dockerfile 0.10%

idempotence4j's Introduction

Release version

idempotence4j

idempotence4j is a lightweight library that provides support for handling idempotent actions.

All actions are persisted to a database and it's expected that client's only going to use database master node to avoid any possible issues caused by the replication lag.

Overview

idempotence4j provides several modules:

  • idempotence4j-core - exposes main API and defines action execution strategy
  • idempotence4j-postgres - PostgreSQL integration, defines flyway migrations, contains PostgreSQL implementation for action repository and locking
  • idempotence4j-mariadb - MariaDb integration, defines flyway migrations, contains MariaDb implementation for action repository and locking
  • idempotence4j-metrics - publishes metrics to io.micrometer registry
  • idempotence4j-spring-boot-starter - auto configuration for IdempotenceService with automatic discovery of DB implementation module

Usage

When invoking idempotence service clients are expected to provide:

  • actionId - unique identifier for the current action
  • onRetry - function that maps persisted result of previously successful action to client result
  • procedure - supplier that executes the action processing logic and returns result to client
  • toRecord - function that maps client result to the one being persisted in the database
  • recordType - type of the stored record required for a later de-serialisation
@AllArgsConstructor
public class ApplicationService {
    private final IdempotenceService idempotenceService;
    private final ResultRepository repository;

    public Result execute(ActionId actionId, String args[]) {
        Result result = idempotenceService.execute(actionId, this::byId, () -> {
            //execution logic
            return new Result();
        }, Result::getId, new TypeReference<ResultId>(){});
        return result;
    }

    private Result byId(ResultId resultId) {
        return repository.get(resultId);
    }
}

Adding idempotence4j to your build

idempotence4j's Maven group ID is com.transferwise.idempotence4j, and its artifact ID is idempotence4j

If you're using Spring Boot here is a quick way of to add a dependency on idempotence4j

dependencies {
  implementation "com.transferwise.idempotence4j:idempotence4j-spring-boot-starter:${project['idempotence4j.version']}"
  implementation "com.transferwise.idempotence4j:idempotence4j-postgres:${project['idempotence4j.version']}"
  implementation "com.transferwise.idempotence4j:idempotence4j-metrics:${project['idempotence4j.version']}"
}

Spring boot starter provides auto-discovery for known implementation modules and autowires service Beans. Otherwise, you can add a dependency on each module individually with core module defined as:

dependencies {
  implementation "com.transferwise.idempotence4j:idempotence4j-core:${project['idempotence4j.version']}"
}

Database modules

idempotence4j comes with a set of database-specific implementations. For now, the library supports only PostgresSQL and MariaDB.

PostgresSQL Module

To add PostgresSQL module to your build using Gradle, use the following:

dependencies {
  implementation "com.transferwise.idempotence4j:idempotence4j-postgres:${project['idempotence4j.version']}"
}

MariaDb Module

To add MariaDb module to your build using Gradle, use the following:

dependencies {
  implementation "com.transferwise.idempotence4j:idempotence4j-mariadb:${project['idempotence4j.version']}"
}

Flyway

โ— Important: Flyway by default doesn't allow to apply "out of order" migrations, that means if you have already applied a migration with version 3, adding migration version 1 will cause an error.

Since idempotence4j is using a timestamp versions it can cause a number of issues, i.e. if in your project you use incremented numeric versions.

Please only use the following configuration approach if your flyway configuration has flyway.outOfOrder flag enabled, otherwise please create an exact copy of these migrations in your project flyway module.

Postgres module contains Flyway migration definitions to keep required tables schemas up-to-date. Both yaml and java configuration examples provided below:

  flyway:
    table: flyway_schema
    password: ${DATASOURCE_FLYWAY_PASSWORD}
    user: ${DATASOURCE_FLYWAY_USERNAME}
    url: ${DATASOURCE_URL}
    locations: classpath:db/migration, classpath:db/idempotence4j/postgres
@Bean
public Flyway getFlyway(dataSource) {
    var configuration = new FluentConfiguration()
        .dataSource(dataSource)
        .locations("classpath:db/migration, classpath:db/idempotence4j/postgres")

    return new Flyway(configuration)
}

Retention

By default action retention is turned off. You can enable and configure it by specifying following parameters:

idempotence4j:
  retention:
    enabled: true
    period: P0Y0M20D              # ISO-8601 format
    purge:
      schedule: "*/15 * * * * ?"  # spring cron format
      batchSize: 150

โ— Important: Please note, if you didn't enable flyway as described in a previous section you need first to define required for db-scheduled tables in your schema

Metrics

Each action execution collects and publishes metrics. idempotence4j-metrics module provides default io.micrometer integration and publishes following metrics:

  • idempotence4j.executions - counter with a set of tags {type, client, outcome}
  • idempotence4j.executions.retries - counter with a set of tags {type, client}
  • idempotence4j.execution.latency - timer with a set of tags {type, client, outcome}

We also provide a common grafana dashboard component that you can include into your provisioned dashboard.

Roadmap

  • Non-transactional execution strategy
  • Payload schema evolution
  • Result payload compression
  • Redis module

idempotence4j's People

Contributors

pturovsk avatar vijayendra-nigam avatar antonio-lopez-tw avatar daveking-tw avatar ivanparker avatar phildobsontw avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.