Using setHandler for executeUpdate

Hello,

I’m really new to Temporal and started developing a workflow which can be triggered via a Client API using Typescript. Following are my client code and workflow code.

Client code:

export const initiateCustomerOffer = async ({ fastify, req }) => {

  // Start workflow execution process
  const { authorization } = req.headers;
  const token = authorization.slice(7);
  const processId = getRequestContext()?.processId;

  const customerIdentifier = crypto.randomUUID();

  try {
    const handle = await fastify.temporalClient.workflow.start(
      Config.get("application.temporal.workflowType"),
      {
        taskQueue: Config.get("application.temporal.taskQueue"),
        args: [{ token, processId, request: req.body }],
        workflowId: customerIdentifier,
        workflowExecutionTimeout: "1 day",
      }
    );

    const initiateCustomerOfferResponse =
      await handle.executeUpdate(
        { name: "retrieveCustomerOffer", type: "update" },
        {
          args: [{ processId }],
        }
      );
    return initiateCustomerOfferResponse;
  } catch (err) {
    handleWorkflowError(err);
  }

Workflow code:

export class CustomerOfferProcessState {
  private mutex: Mutex;
  public getMutex() {
    return this.mutex;
  }

  constructor(
    public token: string,
    public processId: string,
    public customerPosition: RetrieveCustomerPositionStateResponses = [],
    public customerOfferProcessRequest: | InitiateCustomerOfferProcessRequest | undefined = undefined,
    public status: Status = Status.New,
    public version: number = 0,
  ) {
    this.mutex = new Mutex();
  }

export const retrieveCustomerOfferUpdate = workflow.defineUpdate<
  InitiateCustomerOfferProcessResponse,
  [
    params: {
      processId: string;
    }
  ]
>("retrieveLeadReference");
  
  // Workflow
  export async function initiateCustomerOfferProcess(params: {
  token: string;
  processId: string;
  request: InitiateCusomerOfferProcessRequest;
}) {
  const { token, processId, request } = params;
  const {
    leadReference: {
      customerIdentification: { identifier: customerIdentifier },
    },
  } = request;

  const state = new CustomerOfferProcessState(
    token,
    processId
  );
  let release = await state.getMutex().acquire();

  try {
    workflow.setHandler(
      retrieveCustomerOfferUpdate,
      async (params) => {
        workflow.log.info("Handler triggered: Setting status to Accepted");
        state.status = Status.LeadAccepted;
        const { workflowId } = workflow.workflowInfo();
        return createInitiateCustomerOfferResponse({ state, workflowId });
      },
      {
        validator: (params) => {
          workflow.log.info("Validator triggered", params);
          retrieveCustomerOfferValidator(state, params);
        },
      }
    );

    logTechnicalEvent(
      logTypes.LEAD_AND_OPPORTUNITY_MANAGEMENT_WORKFLOW_STARTED,
      "initiateCustomerOfferProcess workflow started",
      { PROCESS_ID: state.processId }
    );   

    state.customerOfferRequest = request;

    const [customerPosition] = await Promise.all([
      retrieveCustomerPositionStateActivity({
        token: state.token,
        processId: state.processId,
        customerId: partyIdentifier,
      }),
    ]);

    state.customerPosition = customerPosition;
    state.version++;
    state.status = Status.LeadInitiated;

    release();
    await workflow.condition(() => state.status == Status.LeadAccepted);


    logTechnicalEvent(
      logTypes.CUSTOMER_OFFER_WORKFLOW_COMPLETED,
      "initiateCustomerOfferProcess workflow completed",
      { PROCESS_ID: state.processId}
    );
  } catch (error) {
    logError(
      logTypes.CUSTOMER_OFFER_WORKFLOW_UNEXPECTED_ERROR,
      "initiateCustomerOfferProcess workflow failed",
      error,
      { PROCESS_ID: state.processId }
    );
    throw error;
  } finally {
 
  }

I have an issue with I’m not reaching the initiateCustomerOfferProcess workflow completed step. Also, I can not see setHandler is triggering (Handler triggered in logs) Can someone suggest a solution please? What am I doing wrong?

Thanks a lot!

Hi @susithapb,

In your Client Code:

const initiateCustomerOfferResponse =
      await handle.executeUpdate(
        { name: "retrieveCustomerOffer", type: "update" },
        {
          args: [{ correlationId }],
        }
      );

Should be:

const initiateCustomerOfferResponse =
      await handle.executeUpdate("retrieveCustomerOffer",
        {
          args: [{ correlationId }],
        }
      );

Hello @anthonywong555 ,

Thanks for the reply. I tried this in the meantime. But still no luck :neutral_face:

Deep dive to some of the attributes to start the Temporal server in local. And found that we have to run the following:

temporal server start-dev --dynamic-config-value frontend.enableUpdateWorkflowExecution=true

After we run the server using this, the updates started to trigger.

Thanks folks!

Oh, that’s indeed possible if you are using an older release of the Temporal CLI. IIRC, Workflow Update should be turned on by default since CLI 1.1.0. Latest is 1.3.0.

1 Like