MultiTrack is designed as a replacement for Tape. Instead of a File Queue we use an SQLite backed queue and is backed by Kotlin Coroutines to provide non-blocking transactions.
Pick which Driver you want to create (we support InMemoryDriver/SqliteDriver/AndroidSqliteDriver).
val driver = AndroidSqliteDriver(applicationContext, "multitrack-database")
Create the Converter which is responsible for parsing your objects into binary - we recommend Moshi
@JsonClass(generateAdapter = true)
data class QueueObject(val id: Int)
val moshi = //.. create moshi instance
val converter = object : MultiTrack.Converter<QueueObject> {
val adapter = moshi.adapter(QueueObject::class.java)
override fun toValue(source: BufferedSource): QueueObject {
return adapter.fromJson(source)
}
override fun fromValue(value: QueueObject, sink: BufferedSink) {
adapter.toJson(sink, value)
}
}
You can pick Coroutine/Callback/RxJava2 interfaces to the queue - note Driver and MultiTrack should be unique once per application.
RxJava2:
val multiTrack = MultiTrack(Schedulers.io(), driver, converter)
Coroutine:
val multiTrack = MultiTrack(Dispatchers.IO, driver, converter)
Java:
val multiTrack = MultiTrack(Executors.newSingleThreadScheduledExecutor(), driver, converter)
With all of these, because the underlying implementation is actor based - it's acceptable to pass in a single thread. However it's not recommended that you use that same single thread after getting a result as you would then be suspending MultiTrack while you do work.
The Queue acts like any other Queue style implementation you push onto the end (tail) of the queue and poll from the front (head) of the queue.
// Write to the queue
multiTrack.push(QueueObject(10)).await()
// 1 Object added to the queue
assert(multiTrack.size().await() == 1) // True
// We look ahead on the queue (peek) - leave the item on the queue.
assert(multiTrack.peek().await().id == 10) // True
// Then read and remove the head of the queue
assert(multiTrack.poll().await().id == 10) // True
// 1 Object added to the queue
assert(multiTrack.size().await() == 0) // True
There is also convenience sizeStream()
for getting queue size callbacks. We recommend using RxJava2 or Coroutine Flow
versions, while there is a Java implementation - the others have much more complete streaming api's.
Default/Kotlin:
- InMemoryDriver
- DefaultMultiTrack
- CoroutineMultiTrack
implementation "com.chrisjenx.multitrack:runtime:$release"
RxJava:
- RxJava2MultiTrack
implementation "com.chrisjenx.multitrack:rxjava2:$release"
Java Sqlite:
- SqliteDriver
implementation "com.chrisjenx.multitrack:driver-sqlite:$release"
Java Sqlite (aar binary):
- AndroidSqliteDriver
implementation "com.chrisjenx.multitrack:driver-android:$release"