Custom StorageProvider
Your database is not supported out of the box? Implement a custom JobRunr StorageProvider for any database.
On this page
JobRunr supports all major SQL and NoSQL databases out of the box. If yours is not listed, you have two options.
Use an API-compatible database
Many databases speak a wire protocol that JobRunr already supports, so you can reuse an existing StorageProvider:
- PostgreSQL-compatible databases (TimescaleDB, YugabyteDB, AWS Aurora PostgreSQL, …) work with the PostgreSQL driver. See PostgreSQL and CockroachDB.
- MySQL-compatible databases (AWS Aurora MySQL, TiDB, …) work with the MySQL driver. See MySQL.
- MongoDB-compatible databases (Amazon DocumentDB, …) work with the MongoDB driver. See Amazon DocumentDB.
If your database is API-compatible with any of these, start there.
NoteSupport for Redis and Elasticsearch was deprecated in JobRunr v7 and removed in v8. If you relied on
LettuceStorageProvider,JedisStorageProvider, orElasticSearchStorageProvider, migrate to one of the supported databases.
Implement a custom StorageProvider
For anything else, you can implement the org.jobrunr.storage.StorageProvider interface yourself. This is what every built-in provider does, so the existing implementations are your best reference - browse them in the JobRunr source on GitHub.
Then register it like any other provider:
JobRunr.configure()
.useStorageProvider(new MyCustomStorageProvider(/* ... */))
.useBackgroundJobServer()
.initialize();
When using a framework, expose your implementation as a StorageProvider bean and JobRunr will pick it up.
Test your implementation thoroughly
A StorageProvider is the backbone of JobRunr - if it misbehaves, jobs are lost, duplicated, or processed more than once. That is why JobRunr ships StorageProviderTest, the same abstract test suite every built-in provider is verified against. To be fully compatible, your implementation has to pass it. It is published as a test fixtures artifact, so you can depend on it directly:
<dependency>
<groupId>org.jobrunr</groupId>
<artifactId>jobrunr</artifactId>
<version>8.8.0</version>
<classifier>test-fixtures</classifier>
<scope>test</scope>
</dependency>
testImplementation testFixtures('org.jobrunr:jobrunr:8.8.0')
Extend it and hand it your provider:
class MyCustomStorageProviderTest extends StorageProviderTest {
@Override
protected StorageProvider getStorageProvider() {
return new MyCustomStorageProvider(/* ... */);
}
@Override
protected void cleanup(int testMethodIndex) {
// wipe the database between tests
}
}
You may deliberately skip part of it. For instance, if you know you will never use recurring jobs, for instance, you can disable those tests. What you cannot skip is making sure the unsupported paths degrade gracefully instead of crashing JobRunr. The InMemoryStorageProvider and its tests are a good, dependency-free starting point to study.
CautionTest exhaustively, including concurrent access from multiple background job servers. JobRunr relies on the
StorageProviderfor distributed coordination; incomplete testing can lead to jobs being processed twice or skipped in production.
Back to the Storage overview.
