vendredi 31 janvier 2020

Design pattern to store context of "sessions" in asynchronous application

Context

I have a running NodeJS application which can be interacted with a CLI.

The communication is done with Websocket: - The CLI emit an Event to run a task in the running NodeJS application - The NodeJS application emit Events to log messages to the CLI

The NodeJS application is huge and completely written in POO with Typescript.

Problem

Imagine I have a class like this:

export class Order {

  public id;
  public customer;
  public total;

  public send() {
    ...
  }

  public static get (orderId: number) {
    return new Order(api.get(orderId));
  }
}

And the socket server like this:

// This event is emitted by the CLI
socket.on('sendOrder', orderId => {
  socket.emit('title', 'Sending order...') // This tell to the CLI to log a title
  const order = Order.get(orderId)         // Retreive the Order
  order.send()                             // Send the Order
  socket.emit('exit', 'Succesfully sent')  // This tell to the CLI to exit with a message
})

I would like to get the current context (in my case, the Socket) from anywhere in my application, example:

export class Order {
  public send() {
    socket.emit('message', 'Sending 34%...')
  }
}

Where am I currently

If I store the context (in my case, the socket) in a "global" variable and run two CLI commands at a time. The second one will override this "global" variable.

So I bring everywhere the Socket with me, example:

export class Order {

  public id;
  public customer;
  public total;

  constructor(private socket: Socket, data) { ... }

  public send() {
    this.socket.emit('message', 'Sending 34%...')
  }

  public static get (socket, orderId: number) {
    return new Order(socket, api.get(orderId));
  }
}
// This event is emitted by the CLI
socket.on('sendOrder', orderId => {
  socket.emit('title', 'Sending order...') // This tell to the CLI to log a title
  const order = Order.get(socket, orderId)         // Retreive the Order
  order.send()                             // Send the Order
  socket.emit('exit', 'Succesfully sent')  // This tell to the CLI to exit with a message
})

Conclusion

Bringing the context everywhere is a pain when the application start to growth.. As a PHP Developer I never had this kind of problem and I couldn't find anything related to my problem on the Web.

Is there any design pattern for my case ?

This question will surely get closed for opinion-based. Fingers crossed.

Aucun commentaire:

Enregistrer un commentaire