当前位置: 首页 > 知识库问答 >
问题:

Cadence工作流区域日期时间参数区域ID转换

夹谷飞龙
2023-03-14

我有一个以UTC的ZonedDatetime作为参数的工作流。在使用测试环境进行单元测试期间,我看到UTC区域在运行工作流时被删除。这种行为的原因是什么?

[更新]事实证明,时区没有被删除,而是以某种方式转换为“Z”的区域ID,而不是原始的“UTC”,尽管它们基本上是相同的。示例代码,

data class WorkflowArgs(
   val currentTime: ZonedDateTime
)

class WorkflowImpl {
    override fun execute(workflowArgs: WorkflowArgs) { 
     activityStub.doSomeActivity(
         workflowArgs.currentTime // Zone ID of "Z"
     )
    }
}

WorkflowClient.start(workflowStub::execute, WorkflowArgs(ZonedDateTime.now(ZoneId.of("UTC")))  // Zone ID of "UTC"

共有1个答案

能逸清
2023-03-14

您需要自定义DataConverter。

DataConvert用于在参数(类)和字节数组之间进行转换,以便客户端可以将参数发送到Cadence服务器,然后服务器将其发送到工作流工作者。

比如可以做如下这样的事情。

注意,这只是您实现DataConverter的一个示例。要编码/解码ZonedDataTime,您需要找到正确的方法。您可能需要参考Spring Data JPA-ZonedDateTime格式来进行json序列化


data class WorkflowArgs(
    val currentTime: ZonedDateTime
)

fun main1() { // this doesn't work
    val dataConverter = JsonDataConverter.getInstance()
    val args = WorkflowArgs( ZonedDateTime.now())
    println(args.currentTime.zone)
    val encoded = dataConverter.toData(args)
    val decoded: WorkflowArgs = dataConverter.fromData(encoded, args.javaClass, args.javaClass)
    println(decoded.currentTime.zone)
    /**
     * Results:
    America/Los_Angeles
    Exception in thread "main" com.uber.cadence.converter.DataConverterException: when parsing:"{"currentTime":{"dateTime":{"date":{"year":2021,"month":9,"day":13},"time":{"hour":9,"minute":14,"second":46,"nano":517000000}},"offset":{"totalSeconds":-25200},"zone":{"id":"America/Los_Angeles"}}}" into following types: [class com.uber.cadence.converter.WorkflowArgs]
    at com.uber.cadence.converter.JsonDataConverter.fromData(JsonDataConverter.java:111)
    at com.uber.cadence.converter.TestZonedDatatimeKt.main(TestZonedDatatime.kt:14)
    at com.uber.cadence.converter.TestZonedDatatimeKt.main(TestZonedDatatime.kt)
    Caused by: java.lang.RuntimeException: Failed to invoke java.time.ZoneId() with no args
    at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:113)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:212)
...
    at com.uber.cadence.converter.JsonDataConverter.fromData(JsonDataConverter.java:109)
    ... 2 more
     */
}

fun main() { // you need to implement another DataConverter like this
    val dataConverter = MyDataConvert()
    val args = WorkflowArgs( ZonedDateTime.now())
    println(args.currentTime.zone)
    val encoded = dataConverter.toData(args)
    val decoded: WorkflowArgs = dataConverter.fromData(encoded, args.javaClass, args.javaClass)
    println(decoded.currentTime.zone)
/**
Resutls:
America/Los_Angeles
America/Los_Angeles
**/
}

class MyDataConvert:DataConverter{

    val originalDataConverter = JsonDataConverter.getInstance()

    override fun toData(vararg value: Any?): ByteArray {
        if( (value.size == 1) && (value[0] is WorkflowArgs)){
            val v = value[0] as WorkflowArgs
            val zoneId = v.currentTime.zone.id
            val br = zoneId.toByteArray()
            return br
        }else{
            return originalDataConverter.toData(value)
        }
    }

    override fun <T : Any?> fromData(content: ByteArray?, valueClass: Class<T>?, valueType: Type?): T {
        if(valueClass!!.canonicalName.contains("WorkflowArgs") ){
            val zi = String(content!!)
            val zoneId: ZoneId = ZoneId.of(zi)
            val dt = ZonedDateTime.now(zoneId)
            return WorkflowArgs(dt) as T
        }else{
            return originalDataConverter.fromData(content, valueClass, valueType)
        }
    }

    override fun fromDataArray(content: ByteArray?, vararg valueType: Type?): Array<Any> {
        if( (valueType.size == 1) && (valueType[0]!!.typeName.contains("WorkflowArgs"))){
            val zi = String(content!!)
            val zoneId: ZoneId = ZoneId.of(zi)
            val dt = ZonedDateTime.now(zoneId)
            val arr = arrayOf(WorkflowArgs(dt))
            return arr as Array<Any>
        }
        return originalDataConverter.fromDataArray(content, *valueType)
    }

}


这是实现DataConverter的另一个示例:https://github.com/uber/cadence-java-samples/pull/37

 类似资料:
  • 我有一个方法可以生成一个随机的日期和时间。 打印输出类似于 我见过几个这样的问题和页面,但他们没有给我一个线索。

  • Highcharts 区域图 以下实例演示了区间区域图。 我们在前面的章节已经了解了 Highcharts 基本配置语法。接下来让我们来看下其他的配置。在 chart 中修改 type 属性。 chart 配置 将 chart 的 type 属性设置为 arearange,chart.type 描述了图表类型。默认值为 "line"。 var chart = { type: 'areara

  • 当我记录这段代码时,我得到了两个输出: 我得到了这些日志: 是否丢失了其原始时区? 我怎么会在乎呢?

  • 我正在尝试在中解析这些日期,然后获取表示形式。 我阅读了这个类似的答案,并创建了一个方法来解析上述日期并返回具有所需格式的: 然而,没有一个图案是匹配的。我这里缺少什么? 更新:在这两个日期中,我都收到了字符的异常。

  • 区域是物理概念,代表数据中心的地理区域。 区域是物理概念,代表数据中心的地理区域。 区域来源: 本地IDC:在部署云管平台过程中会设置本地IDC的区域和可用区信息,部署完成后只支持添加可用区。 私有云:同步已连接私有云账号上的区域和可用区信息。 入口:在云管平台单击左上角导航菜单,在弹出的左侧菜单栏中单击 “网络/地域/区域” 菜单项,进入区域列表。 查看区域详情 该功能用于查看区域的详细信息。

  • 我偶然创建了一个错误的域名,或者经过一些测试后,我想删除该域名。我应该那样做吗?又是怎么做到的?