MCPcopy Index your code
hub / github.com/VilledeMontreal/workit

github.com/VilledeMontreal/workit @v7.0.2

Chat with this repo
repository ↗ · DeepWiki ↗ · release v7.0.2 ↗ · + Follow
500 symbols 1,187 edges 222 files 44 documented · 9%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

WorkIt 🚀

License: MIT lerna npm

Worker extensible pour Node.js fonctionnant avec les plates-formes AWS Step function et Camunda BPM optimisées par TypeScript

🚦 Motivation

Nous avions besoin d'un framework pour nous aider à développer rapidement des Workers. Ces derniers sont utilisés pour exécuter des tâches.

Ce framework offre les avantages suivants : - Expérimenter et choisir la plate-forme Camunda, AWS Step Functions ou d'autres sans réécrire la logique métier. - Au lieu de dépendre directement d'un client Camunda, ce projet fournit une couche d'abstraction. De cette façon, il est plus facile de changer de client ou de créer le vôtre. - Vous voulez avoir une standardisation des workers. - L'uniformisation. En effet, vous pouvez utiliser plusieurs plates-formes en fonction des besoins du projet. - Ajout de fonctionnalités comme l'automatisation des traces (incluant la propagation). - Ce Framework impose la parité des fonctionnalités entre AWS Step Functions et Camunda BPM via les bibliothèques clientes. Certaines fonctionnalités exposées à la plate-forme Camunda BPM ne sont pas présentes dans ce package car nous ne pourrions pas les fournir si nous passons à AWS Step Functions. Cette limitation est destinée à guider les développeurs dans la préparation de la migration.

🏁 Démarrage rapide

Commencez en 2 minutes.

📚 Documentation

📦 Librairies

🔧 API

Librairie Description
workit-types Cette librairie fournit les interfaces / enums TypeScript pour les classes de Workit
workit-core Cette librairie fournit les implémentations par défaut de la librairie "Workit types"

🔌 Implémentation / Clients

Librairie Description
workit-bpm-client Ce module fournit un contrôle complet pour intéragir avec la plateforme Camunda Bpm.

Il utilise camunda-external-task-client-js par défaut. | | workit-stepfunction-client | Ce module fournit un contrôle complet pour intéragir avec la plateforme Step functions.

Par défaut, il utilise @aws-sdk/client-sqs, @aws-sdk/client-sfn. |


⚙️ Installation

npm i @villedemontreal/workit

ou utiliser le générateur en dessous

⚡ Comment utiliser

Basculer entre les plateformes est simple, il suffit de spécifier un TAG pour l'IoC.

  • TAG.camundaBpm (Camunda)
  • TAG.stepFunction (AWS Step Functions)

▶️ Rouler le worker

const worker = IoC.get<Worker>(CORE_IDENTIFIER.worker, TAG.camundaBpm);

worker.start();
worker.run();

📤 Déployer un workflow

const manager = IoC.get<IWorkflowClient>(CORE_IDENTIFIER.client_manager, TAG.camundaBpm);
const fullpath = `${process.cwd()}/sample/BPMN_DEMO.bpmn`;
await manager.deployWorkflow(fullpath);

📋 Obtenir les flux de travail

const manager = IoC.get<IWorkflowClient>(CORE_IDENTIFIER.client_manager, TAG.camundaBpm);
await manager.getWorkflows()

📄 Obtenir un flux de travail

const manager = IoC.get<IWorkflowClient>(CORE_IDENTIFIER.client_manager, TAG.camundaBpm);
await manager.getWorkflow({ bpmnProcessId: "DEMO" });

🆕 Créer une instance de flux de travail

const manager = IoC.get<IWorkflowClient>(CORE_IDENTIFIER.client_manager, TAG.camundaBpm);
await manager.createWorkflowInstance({
    bpmnProcessId: "MY_BPMN_KEY",
    variables: {
        hello: "world"
    }
});

🛠️ Définir les tâches (vos activités bpmn)

Vous pouvez définir plusieurs tâches pour un seul Worker. Il traitera tous les messages et acheminera les requêtes vers les bonnes tâches.

export class HelloWorldTask extends TaskBase<IMessage> {
  // You can type message like IMessage<TBody, TProps> default any
  public execute(message: IMessage): Promise<IMessage> {
      const { properties } = message;
      console.log(`Executing task: ${properties.activityId}`);
      console.log(`${properties.bpmnProcessId}::${properties.processInstanceId} Servus!`);
      // put your business logic here
      return Promise.resolve(message);
  }
}


enum LOCAL_IDENTIFIER {
    // sample_activity must match the activityId in your bpmn
    sample_activity= 'sample_activity'
}

// Register your task
IoC.bindTo(HelloWorldTask, LOCAL_IDENTIFIER.sample_activity);

Vous pouvez même faire des liaisons complexes comme :

IoC.bindTask(HelloWorldTaskV2, LOCAL_IDENTIFIER.activity1, { bpmnProcessId: BPMN_PROCESS_ID, version: 2 });

🔄 Cycle de vie et événements des Workers

const worker = IoC.get<Worker>(CORE_IDENTIFIER.worker, TAG.camundaBpm); 
// or TAG.camundaBpm

worker.once('starting', () => {
    // slack notification 
});

worker.once('stopping', () => {
    // close connections
});

worker.once('stopped', () => {
    // slack notification
});

const handler = worker.getProcessHandler();

handler.on('message', (msg: IMessage) => {
    // log/audit
});

handler.on('message-handled', (err: Error, msg: IMessage) => {
    if (err) {
        // something wrong
    } else {
        // everything is fine
    }
});

worker.start();
worker.run(); // Promise
worker.stop(); // Promise

🛡️ Les intercepteurs

const workerConfig = {
  interceptors: [
    async (message: IMessage): Promise<IMessage> => {
      // do something before we execute task.
      return message;
    }
  ]
};

IoC.bindToObject(workerConfig, CORE_IDENTIFIER.worker_config);

📈 Open-telemetry

Par défaut, nous lions un NoopTracer mais vous pouvez en fournir un et il doit étendre Tracer. Nous vous recommandons fortement d'utiliser ce type de pattern dans vos tâches : le pattern "Domain Probe". Mais voici un exemple :

// Simply bind your custom tracer object like this
IoC.bindToObject(tracer, CORE_IDENTIFIER.tracer);
export class HelloWorldTask extends TaskBase<IMessage> {
  private readonly _tracer: Tracer;

  constructor(tracer: Tracer) {
        this._tracer = tracer
  }

  public async execute(message: IMessage): Promise<IMessage> {
      const { properties } = message;

      console.log(`Executing task: ${properties.activityId}`);
      console.log(`${properties.bpmnProcessId}::${properties.processInstanceId} Servus!`);

      // This call will be traced automatically
      const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1');

      // you can also create a custom trace like this :
      const currentSpan = tracer.getCurrentSpan();
      const span = this._tracer.startSpan('customSpan', {
        parent: currentSpan,
        kind: SpanKind.CLIENT,
        attributes: { key: 'value' },
      });

      console.log();
      console.log('data:');
      console.log(response.data);
      // put your business logic here

      // finish the span scope
      span.end();

      return Promise.resolve(message);
  }
}

Vous pouvez consulter le dossier sample où nous fournissons un exemple (parallel.ts) en utilisant Jaeger.

📖 Voir le tutoriel relié aux traces


⚙️ Définissez votre configuration pour la plate-forme que vous souhaitez utiliser

TODO: show for step function


🧩 Définissez vos stratégies en cas d'échec ou de succès

Par défaut, nous définissons une stratégie simple de réussite ou d'échec. Nous vous recommandons vivement de fournir la vôtre car votre application déclenche des exceptions spécifiques. Les stratégies sont automatiquement traitées. Si une exception se dégage de la tâche, une stratégie d'échec est invoquée, sinon c'est un succès et la stratégie de succès est invoquée.

// the idea is to create your own but imagine that your worker works mainly with HTTP REST API
class ServerErrorHandler extends ErrorHandlerBase {
  constructor(config: { maxRetries: number }) {
    super(config);
  }

  public isHandled(error: IErrorResponse<IResponse<IApiError>>): boolean {
    return error.response.status >= 500;
  }
  public handle(error: IErrorResponse<IResponse<IApiError>>, message: IMessage): Failure {
    const retries = this.getRetryValue(message);
    return new Failure(error.message, this.buildErrorDetails(error, message), retries, 2000 * retries);
  }
}

// You got the idea...

// You could create also
// BadRequestErrorHandler
// TimeoutErrorHandler
// UnManagedErrorHandler
// ...
// Then you could build your strategy
/// "FailureStrategy" implements "IFailureStrategy", this interface is provided by workit
const strategy = new FailureStrategy([
  new AxiosApiErrorHandler(errorConfig, [
    new BadRequestErrorHandler(errorConfig),
    new TimeoutErrorHandler(errorConfig),
    new ServerErrorHandler(errorConfig),
    new UnManagedErrorHandler(errorConfig),
    //...
  ]),
  new ErrorHandler(errorConfig)
]);
// worker will use your new strategy
IoC.bindToObject(strategy, CORE_IDENTIFIER.failure_strategy);

🧪 Rouler les tests

Nous utilisons Jest.

npm test

🏗️ Construit avec


💡 Philosophie

  1. Permettre aux développeurs Javascript d'écrire du code conforme aux principes SOLID.
  2. Faciliter et encourager l'adhésion aux meilleures pratiques de POO et d'IoC.
  3. Ajouter le moins de surcharge d'exécution possible.

🐳 Docker

🏢 Camunda BPM

docker run -d --name camunda -p 8080:8080 camunda/camunda-bpm-platform:latest
// Go: http://localhost:8080/camunda - user/password : `demo/demo`

📖 Plus de détails


🏷️ Gestion des versions

Nous utilisons SemVer pour la gestion des versions. Pour les versions disponibles, voir les balises sur ce référentiel.

workit AWS Step function Camunda BPM
>=6.0.0 tous 7.6 to latest

👥 Mainteneurs

Voir aussi la liste des contributeurs ayant participé à ce projet.


🤝 Contribuer

Veuillez lire CONTRIBUTING.md pour plus de détails sur notre code de conduite et sur le processus de soumission des demandes.


📄 Licence

Ce projet est sous licence MIT - voir le fichier LICENSE pour plus de détails

Extension points exported contracts — how you extend this code

IClient (Interface)
(no doc) [7 implementers]
packages/workit-types/src/core/client.ts
ITestService (Interface)
(no doc) [6 implementers]
packages/workit-core/tests/units/IoC.spec.ts
IHandlerStrategy (Interface)
(no doc) [2 implementers]
examples/failure-strategy/src/failure-strategy.ts
IMetricsService (Interface)
(no doc) [2 implementers]
examples/plugin-metrics/src/plugins/metrics-plugin.ts
ITopicSubscription (Interface)
(no doc) [7 implementers]
packages/workit-types/src/camundaBpm/topicSubscription.ts
IMetricsPluginConfig (Interface)
(no doc)
examples/plugin-metrics/src/plugins/metrics-plugin.ts
ITask (Interface)
(no doc) [15 implementers]
packages/workit-types/src/tasks/task.ts
IWorkflowClient (Interface)
(no doc) [5 implementers]
packages/workit-types/src/core/camunda/workflowClient.ts

Core symbols most depended-on inside this repo

get
called by 111
packages/workit-types/src/core/ioc.ts
map
called by 52
packages/workit-stepfunction-client/src/sfnSqsMapperProperties.ts
bindTo
called by 41
packages/workit-types/src/core/ioc.ts
deployWorkflow
called by 27
packages/workit-types/src/core/camunda/workflowClient.ts
bindToObject
called by 25
packages/workit-types/src/core/ioc.ts
map
called by 25
packages/workit-bpm-client/src/camundaMapperProperties.ts
on
called by 24
packages/workit-types/src/process/process.ts
increment
called by 24
examples/plugin-metrics/src/plugins/metrics-plugin.ts

Shape

Method 246
Class 115
Interface 70
Function 63
Enum 6

Languages

TypeScript100%

Modules by API surface

examples/plugin-metrics/src/plugins/metrics-plugin.ts30 symbols
packages/workit-bpm-client/src/camundaBpmClient.ts18 symbols
packages/workit-core/src/IoC.ts17 symbols
packages/workit-bpm-client/src/utils/utils.ts17 symbols
packages/workit-stepfunction-client/src/sfnSQSClient.ts16 symbols
packages/workit-bpm-client/src/repositories/camundaRepository.ts16 symbols
packages/workit-core/tests/units/IoC.spec.ts12 symbols
packages/workit/src/camunda-n-mq/clientManager.ts11 symbols
packages/workit-types/src/camundaBpm/camundaRepository.ts11 symbols
packages/workit-types/src/core/camunda/workflowClient.ts10 symbols
examples/failure-strategy/src/failure-strategy.ts10 symbols
packages/workit/tests/utils/fake.ts9 symbols

For agents

$ claude mcp add workit \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact