All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.pubnub.api.endpoints.remoteaction.ComposableRemoteAction.kt Maven / Gradle / Ivy

package com.pubnub.api.endpoints.remoteaction

import com.pubnub.api.PubNubException
import com.pubnub.api.enums.PNOperationType
import com.pubnub.api.v2.callbacks.Result
import java.util.function.Consumer

class ComposableRemoteAction(
    private val remoteAction: ExtendedRemoteAction,
    private val createNextRemoteAction: (T) -> ExtendedRemoteAction,
    private var checkpoint: Boolean,
) : ExtendedRemoteAction {
    private var nextRemoteAction: ExtendedRemoteAction? = null
    private var isCancelled = false

    fun  then(factory: (U) -> ExtendedRemoteAction): ComposableRemoteAction {
        return ComposableRemoteAction(this, factory, false)
    }

    @Synchronized
    fun checkpoint(): ComposableRemoteAction {
        checkpoint = true
        return this
    }

    @Throws(PubNubException::class)
    override fun sync(): U {
        return remoteAction.sync().let { result ->
            createNextRemoteAction(result).sync()
        }
    }

    override fun async(callback: Consumer>) {
        remoteAction.async { r: Result ->
            r.onFailure {
                callback.accept(Result.failure(it.copy(remoteAction = this)))
            }.onSuccess {
                try {
                    synchronized(this) {
                        if (!isCancelled) {
                            val newNextRemoteAction =
                                createNextRemoteAction(it) // if s is not error r shouldn't be null
                            nextRemoteAction = newNextRemoteAction
                            newNextRemoteAction.async { r2: Result ->
                                r2.onFailure {
                                    callback.accept(Result.failure(it.copy(remoteAction = this)))
                                }.onSuccess {
                                    callback.accept(Result.success(it))
                                }
                            }
                        }
                    }
                } catch (ex: PubNubException) {
                    callback.accept(Result.failure(ex.copy(remoteAction = this)))
                }
            }
        }
    }

    @Synchronized
    override fun retry() {
        if (checkpoint && nextRemoteAction != null) {
            nextRemoteAction!!.retry()
        } else {
            remoteAction.retry()
        }
    }

    @Synchronized
    override fun silentCancel() {
        isCancelled = true
        remoteAction.silentCancel()
        if (nextRemoteAction != null) {
            nextRemoteAction!!.silentCancel()
        }
    }

    override fun operationType(): PNOperationType {
        return nextRemoteAction?.operationType() ?: remoteAction.operationType()
    }

    class ComposableBuilder(private val remoteAction: ExtendedRemoteAction) {
        private var checkpoint = false

        fun  then(factory: (T) -> ExtendedRemoteAction): ComposableRemoteAction {
            return ComposableRemoteAction(remoteAction, factory, checkpoint)
        }

        fun checkpoint(): ComposableBuilder {
            checkpoint = true
            return this
        }
    }

    companion object {
        fun  firstDo(remoteAction: ExtendedRemoteAction): ComposableBuilder {
            return ComposableBuilder(remoteAction)
        }
    }
}