observeRegistry without Subscription

I need help with the following scenario:
I get an order from SAP via the Actyx-http-Connector. This order contains several processes. I want to give these processes a priority before I send them as an event to Actyx.

In order to determine the priority, I need all processes that exist so far.

With my currently implemented solution, I am encountering two problems:

  1. when i emit the order, i send an empty array “ListOfProcesses” because the getProcessPriority function has not been executed yet.
  2. as soon as the order is emitted, the getProcessPriority function is executed again, because I still have subscribed the RegistryTwin.

Is there a way to get the state of all twins in the RegistryTwin without having to subscribe to the twin? Or without having to call a callback function?

There is something amiss due to concurrency:
observeRegistry returns immediately. Your callback is called later. In the meantime, the event is emitted with the initial empty array.

What you can do is

  • observe the registry to get all the relevant order twins within a Promise
  • cancel the subscription immediately within its callback
  • observe each individual order to get its state, again within a Promise
  • and resolve the outer Promise with the state computation Promises created in the previous step.

Then you can simply await getting the list of processes and emit the created event.

Here is what it would look like, roughly:

const getExistingProcesses = (): Promise<any> => new Promise(resolve => {
  const cancelRegistryObservation = pond.observe(OrderRegistryTwin.registry, async allOrders => {
    cancelRegistryObservation()
    resolve(
      Promise.all(
        Object.keys(allOrders)
          .map(orderId => new Promise<any>(resolve => {
            const cancelOrderObservation = pond.observe(OrderTwin.of(orderId), (orderState) => {
              cancelOrderObservation()
              resolve(orderState.processes)
            })
          }))
      )
    )
  })
})

const existingProcesses = await getExistingProcesses()
console.log(existingProcesses.flat())

// calculate the priority and emit event

You might want to review the types used since I just guessed how your Orders might look like. I also omitted error handling for illustration purposes.

In this scenario, you basically manually take care of the hydration of individual entities, which is what the registry does internally as well. There might be some optimizations in there, but I’m not quite sure ATM.

However, this might not be the smartest way to go about it, as you’ll always calculate the complete list of processes before emitting the created event based on all registered orders.

From what I understood, a simpler and possibly faster way to go about it would be to create a separate twin to track all processes required for calculating priorities and just observe and await this one. This way, you need to jump through one hoop less to get the list.

Sorry for the delayed response, I hope this helps. Let us know if you need further assistance.

1 Like