为什么要通过corda NodeSchedulerService重新安排SchedulableState?

时间:2018-06-08 14:46:53

标签: corda

我有一个Cordapp,它使用SchedulableState在某个时间t安排活动。当我的应用程序在时间t执行时,日志会报告:

ScheduledStateRef(ref=5E4BE64EEFF9D9715043F70D8E8E1AB64B51CE3CC68E60BEFC43F5A545D66B9D(0), scheduledAt=2018-06-08T14:13:
  01.549Z) has rescheduled to 2018-06-08T14:23:01.549Z. {actor_id=node, actor_owningIdentity=O=NODE, L=London, C=GB, actor_store_id=NODE_CONFIG, invocation_id=be1b1b7a-38cd-46b0-adb7-2e6b016c54ef, invocation_timestamp=2018-06-08T14:13:0
  0.085Z, session_id=146f442e-4d0b-45d2-a3a2-b01ddafdf8c3, session_timestamp=2018-06-08T13:51:28.771Z}

永远不会执行相对流程。这发生在我升级到3.1时。

站在这里的代码

https://github.com/corda/corda/blob/release-V3.1/node/src/main/kotlin/net/corda/node/services/events/NodeSchedulerService.kt#L286

条件scheduledActivity.scheduledAt.isAfter(services.clock.instant())不应该在我的情况下,或者我错了吗?

编辑:这是预定状态

    @CordaSerializable
data class Deal(val externalNode: Party,
                val initializer: Party,
                val acceptor: Party,
                val token: Currency,
                val initializerStatus: MemberStatus = MemberStatus.REGULAR,
                val acceptorStatus: MemberStatus = MemberStatus.REGULAR,
                val timestamp: Long = Instant.now().toEpochMilli(),
                val frequency: Long = 1.days, 
                val expiration: Long = Instant.now().toEpochMilli() + 180.days.times(1000),
                var status: DealStatus = DealStatus.PROPOSED,
                val errorMessage: String = "",
                val errorType: ErrorType = ErrorType.NONE,
                val regulators: List<Party> = emptyList(),
                val optionalRescheduling: Instant? = null,
                override val linearId: UniqueIdentifier = UniqueIdentifier()) : LinearState, SchedulableState {

    // Keys
    var scheduledFlow: String = ""
        private set

    val externalNodeKey = externalNode.owningKey
    val initializerKey = initializer.owningKey
    val acceptorKey = acceptor.owningKey

    // Parties involved
    val parties = listOf(acceptor, initializer)
    override val participants = listOf(externalNode, initializer, acceptor)

    // Next payment scheduled at
    val nextActivityTime = nextInstant()

    override fun nextScheduledActivity(thisStateRef: StateRef,
                                       flowLogicRefFactory: FlowLogicRefFactory): ScheduledActivity? {

        return if (nextActivityTime != null) try {
                val scheduledFlowRef = Class.forName(scheduledFlow) as Class<FlowLogic<*>>
                loggerFor<Deal>().info("\n *** Performing $scheduledFlow at $nextActivityTime ***")
                return ScheduledActivity(flowLogicRefFactory.create(scheduledFlowRef, thisStateRef), nextActivityTime)
            } catch (e: ClassNotFoundException) {
                loggerFor<Deal>().info("\n *** Flow class not found for $linearId ***")
                null
            }
        else null

    }

    private fun nextInstant(): Instant? = when (status) {
                DealStatus.PROPOSED -> setExpirationInstant()
                DealStatus.PENDING -> setExpirationInstant()
                DealStatus.ACTIVE -> setNextCall()
                DealStatus.CLOSED -> null
                DealStatus.CANCELED -> null
    }

    private fun setExpirationInstant(): Instant {
        loggerFor<Deal>().info("\n *** Setting expiration instant $linearId with status $status ***")
        scheduledFlow = "demo.flows.triggers.CloseDealFlow\$WithExpiration"
        return Instant.ofEpochMilli(expiration)
    }

    private fun setNextCall(): Instant? {

        require(frequency > 0) { "Frequency should be positive" }

        val frequencyMillis = frequency * 1000
        val numOfDaysPassed = (Instant.now().toEpochMilli() - timestamp).div(frequencyMillis)
        val nextCallInstant = optionalRescheduling ?: Instant.ofEpochMilli(timestamp + (numOfDaysPassed + 1).times(frequencyMillis))

        val expirationInstant = Instant.ofEpochMilli(expiration)
        val rescheduledLabel = if (optionalRescheduling != null) "re-scheduled at $optionalRescheduling" else ""


        return if (expirationInstant.isBefore(nextCallInstant)) {
            scheduledFlow = "demo.flows.triggers.CloseDealFlow\$WithExpiration"
            expirationInstant
        } else {
            scheduledFlow = "demo.flows.triggers.VariationMarginFlow\$Solver"
            nextCallInstant
        }
    }


    fun isInitializer(party: Party): Boolean = (initializer == party)

    fun isAcceptor(party: Party): Boolean = (acceptor == party)

}

0 个答案:

没有答案