From 7643483b3d30640bbfb1ef9dbca5d3d6ad770e07 Mon Sep 17 00:00:00 2001 From: Sindre Wilting Date: Mon, 28 Sep 2020 20:13:32 +0200 Subject: [PATCH 1/5] Remove ExecutionContextManager and fix everything that broke. --- Samples/Basic/index.ts | 36 +++-- Samples/Container/index.ts | 7 +- Samples/EventHorizon/index.ts | 7 +- Source/eventHorizon/EventHorizons.ts | 10 +- Source/eventHorizon/EventHorizonsBuilder.ts | 8 +- .../events.filtering/EventFiltersBuilder.ts | 11 +- .../Internal/EventFilterProcessor.ts | 12 +- .../Internal/FilterEventProcessor.ts | 6 +- .../PartitionedEventFilterProcessor.ts | 12 +- .../Internal/PublicEventFilterProcessor.ts | 12 +- .../PartitionedEventFilterBuilder.ts | 8 +- .../PrivateEventFilterBuilder.ts | 8 +- .../PublicEventFilterBuilder.ts | 8 +- .../UnpartitionedEventFilterBuilder.ts | 8 +- Source/events.handling/EventHandlers.ts | 8 +- .../events.handling/EventHandlersBuilder.ts | 6 +- .../Internal/EventHandlerProcessor.ts | 19 ++- .../Internal/EventProcessor.ts | 19 ++- Source/events/EventStore.ts | 8 +- Source/events/EventStoreBuilder.ts | 137 +++--------------- .../execution/ExecutionContextExtensions.ts | 43 ++++++ Source/execution/ExecutionContextManager.ts | 98 ------------- Source/execution/IExecutionContextManager.ts | 26 ---- ...rom_two_different_nested_async_contexts.ts | 44 ------ Source/execution/index.ts | 4 +- Source/sdk/Client.ts | 106 ++++++++++---- Source/sdk/LoggingBuilder.ts | 2 +- Source/services/IReverseCallClient.ts | 3 +- Source/services/ReverseCallClient.ts | 14 +- 29 files changed, 271 insertions(+), 419 deletions(-) create mode 100644 Source/execution/ExecutionContextExtensions.ts delete mode 100644 Source/execution/ExecutionContextManager.ts delete mode 100644 Source/execution/IExecutionContextManager.ts delete mode 100644 Source/execution/for_ExecutionContextManager/when_getting_context_from_two_different_nested_async_contexts.ts diff --git a/Samples/Basic/index.ts b/Samples/Basic/index.ts index 5278ad91..9b2f2277 100644 --- a/Samples/Basic/index.ts +++ b/Samples/Basic/index.ts @@ -21,32 +21,30 @@ const client = Client .forMicroservice('7a6155dd-9109-4488-8f6f-c57fe4b65bfb', microservice => { microservice.withVersion(Version.first); }) - .withEventStore(eventStore => { - eventStore.withFilters(filterBuilder => { - filterBuilder.createPrivateFilter('79e12ab3-2751-47e1-b959-d898dc4d6ee8', fb => { - fb - .handle((event: any, context: EventContext) => { - return new Promise((resolve, reject) => { - console.log('Filtering event', event); - }); + .withFilters(filterBuilder => { + filterBuilder.createPrivateFilter('79e12ab3-2751-47e1-b959-d898dc4d6ee8', fb => { + fb + .handle((event: any, context: EventContext) => { + return new Promise((resolve, reject) => { + console.log('Filtering event', event); }); - }); - filterBuilder.createPublicFilter('2c087657-b318-40b1-ae92-a400de44e507', fb => { - fb - .handle((event: any, context: EventContext) => { - return new PartitionedFilterResult(true, PartitionId.unspecified); - }); - }); + }); + }); + filterBuilder.createPublicFilter('2c087657-b318-40b1-ae92-a400de44e507', fb => { + fb + .handle((event: any, context: EventContext) => { + return new PartitionedFilterResult(true, PartitionId.unspecified); + }); }); }) .build(); -client.executionContextManager.forTenant('900893e7-c4cc-4873-8032-884e965e4b97'); - - const event = new MyEvent(); event.anInteger = 42; event.aString = 'Forty two'; -client.eventStore.commitPublic(event, 'd8cb7301-4bec-4451-a72b-2db53c6dc05d'); +client + .eventStore + .forTenant('900893e7-c4cc-4873-8032-884e965e4b97') + .commitPublic(event, 'd8cb7301-4bec-4451-a72b-2db53c6dc05d'); diff --git a/Samples/Container/index.ts b/Samples/Container/index.ts index 9b31ca9b..ccb07de7 100644 --- a/Samples/Container/index.ts +++ b/Samples/Container/index.ts @@ -16,9 +16,10 @@ const client = Client .withLogging(_ => _.useWinston(_ => _.level = 'debug')) .build(); -client.executionContextManager.forTenant('900893e7-c4cc-4873-8032-884e965e4b97'); - const event = new MyEvent(); event.anInteger = 42; event.aString = 'Forty two'; -client.eventStore.commit(event, 'd8cb7301-4bec-4451-a72b-2db53c6dc05d'); +client + .eventStore + .forTenant('900893e7-c4cc-4873-8032-884e965e4b97') + .commit(event, 'd8cb7301-4bec-4451-a72b-2db53c6dc05d'); diff --git a/Samples/EventHorizon/index.ts b/Samples/EventHorizon/index.ts index cc23f40c..3228c59b 100644 --- a/Samples/EventHorizon/index.ts +++ b/Samples/EventHorizon/index.ts @@ -32,10 +32,11 @@ const client = Client }) .build(); -client.executionContextManager.forTenant('900893e7-c4cc-4873-8032-884e965e4b97'); - const event = new MyEvent(); event.anInteger = 42; event.aString = 'Forty two'; -client.eventStore.commitPublic(event, 'd8cb7301-4bec-4451-a72b-2db53c6dc05d'); +client + .eventStore + .forTenant('900893e7-c4cc-4873-8032-884e965e4b97') + .commitPublic(event, 'd8cb7301-4bec-4451-a72b-2db53c6dc05d'); diff --git a/Source/eventHorizon/EventHorizons.ts b/Source/eventHorizon/EventHorizons.ts index 6f2fb6f8..efd8fc32 100644 --- a/Source/eventHorizon/EventHorizons.ts +++ b/Source/eventHorizon/EventHorizons.ts @@ -4,7 +4,7 @@ import { Guid } from '@dolittle/rudiments'; import { Logger } from 'winston'; import * as grpc from 'grpc'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { callContexts, failures, guids } from '@dolittle/sdk.protobuf'; import { SubscriptionsClient } from '@dolittle/runtime.contracts/Runtime/EventHorizon/Subscriptions_grpc_pb'; import { Subscription as PbSubscription, SubscriptionResponse as PbSubscriptionResponse } from '@dolittle/runtime.contracts/Runtime/EventHorizon/Subscriptions_pb'; @@ -25,14 +25,14 @@ export class EventHorizons implements IEventHorizons { /** * Initializes a new instance of {@link EventHorizons}. * @param {SubscriptionsClient} subscriptionsClient The runtime client for working with subscriptions. - * @param {IExecutionContextManager} executionContextManager For Managing execution context. + * @param {ExecutionContext} executionContext The execution context. * @param {TenantWithSubscriptions[]} tenantSubscriptions Tenant subscriptions to connect. * @param {SubscriptionCallbacks} callbacks Callbacks for handling responses of subscribing. * @param {Logger} logger Logger for logging; */ constructor( private _subscriptionsClient: SubscriptionsClient, - private _executionContextManager: IExecutionContextManager, + private _executionContext: ExecutionContext, readonly subscriptions: TenantWithSubscriptions[], readonly callbacks: SubscriptionCallbacks, private _logger: Logger) { @@ -56,11 +56,11 @@ export class EventHorizons implements IEventHorizons { const consumerTenant = tenantWithSubscriptions.tenant; for (const subscription of tenantWithSubscriptions.subscriptions) { - this._executionContextManager.forTenant(consumerTenant); + const executionContext = this._executionContext.forTenant(consumerTenant.value); this._logger.debug(`Subscribing to events from ${subscription.partition} in ${subscription.stream} of ${subscription.tenant} in ${subscription.microservice} for ${consumerTenant} into ${subscription.scope}`); - const callContext = callContexts.toProtobuf(this._executionContextManager.current); + const callContext = callContexts.toProtobuf(executionContext); callContext.setHeadid(guids.toProtobuf(Guid.create())); const pbSubscription = new PbSubscription(); diff --git a/Source/eventHorizon/EventHorizonsBuilder.ts b/Source/eventHorizon/EventHorizonsBuilder.ts index 4e90189e..668be4e2 100644 --- a/Source/eventHorizon/EventHorizonsBuilder.ts +++ b/Source/eventHorizon/EventHorizonsBuilder.ts @@ -1,7 +1,7 @@ // Copyright (c) Dolittle. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -import { TenantId, IExecutionContextManager } from '@dolittle/sdk.execution'; +import { TenantId, ExecutionContext } from '@dolittle/sdk.execution'; import { SubscriptionsClient } from '@dolittle/runtime.contracts/Runtime/EventHorizon/Subscriptions_grpc_pb'; import { Logger } from 'winston'; @@ -70,15 +70,15 @@ export class EventHorizonsBuilder { /** * Build all configured {@link TenantSubscriptions} * @param {SubscriptionsClient} subscriptionsClient The runtime client for working with subscriptions. - * @param {IExecutionContextManager} executionContextManager For Managing execution context. + * @param {ExecutionContext} executionContext The execution context. * @param {Logger} logger Logger for logging; * @returns {TenantSubscriptions[]} */ - build(subscriptionsClient: SubscriptionsClient, executionContextManager: IExecutionContextManager, logger: Logger): IEventHorizons { + build(subscriptionsClient: SubscriptionsClient, executionContext: ExecutionContext, logger: Logger): IEventHorizons { const tenantSubscriptions = this._tenantSubscriptionsBuilders.map(_ => _.build()); return new EventHorizons( subscriptionsClient, - executionContextManager, + executionContext, tenantSubscriptions, this.callbacks, logger); diff --git a/Source/events.filtering/EventFiltersBuilder.ts b/Source/events.filtering/EventFiltersBuilder.ts index b2b2fd73..9bdd68b6 100644 --- a/Source/events.filtering/EventFiltersBuilder.ts +++ b/Source/events.filtering/EventFiltersBuilder.ts @@ -3,8 +3,10 @@ import { Logger } from 'winston'; +import { Guid } from '@dolittle/rudiments'; + import { IArtifacts } from '@dolittle/sdk.artifacts'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { Cancellation } from '@dolittle/sdk.resilience'; import { FiltersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/Filters_grpc_pb'; @@ -13,7 +15,6 @@ import { FilterId } from './FilterId'; import { Filters } from './Filters'; import { IFilters } from './IFilters'; import { PublicEventFilterBuilder } from './PublicEventFilterBuilder'; -import { Guid } from '@dolittle/rudiments'; import { PrivateEventFilterBuilder } from './PrivateEventFilterBuilder'; @@ -63,18 +64,18 @@ export class EventFiltersBuilder { */ build( client: FiltersClient, - executionContextManager: IExecutionContextManager, + executionContext: ExecutionContext, artifacts: IArtifacts, logger: Logger, cancellation: Cancellation): IFilters { const filters = new Filters(logger); for (const privateFilterBuilder of this._privateFilterBuilders) { - const filterProcessor = privateFilterBuilder.build(client, executionContextManager, artifacts, logger); + const filterProcessor = privateFilterBuilder.build(client, executionContext, artifacts, logger); filters.register(filterProcessor, cancellation); } for (const publicFilterBuilder of this._publicFilterBuilders) { - const filterProcessor = publicFilterBuilder.build(client, executionContextManager, artifacts, logger); + const filterProcessor = publicFilterBuilder.build(client, executionContext, artifacts, logger); filters.register(filterProcessor, cancellation); } diff --git a/Source/events.filtering/Internal/EventFilterProcessor.ts b/Source/events.filtering/Internal/EventFilterProcessor.ts index 83bf1acd..617b6087 100644 --- a/Source/events.filtering/Internal/EventFilterProcessor.ts +++ b/Source/events.filtering/Internal/EventFilterProcessor.ts @@ -6,7 +6,7 @@ import { Logger } from 'winston'; import { Guid } from '@dolittle/rudiments'; import { IArtifacts } from '@dolittle/sdk.artifacts'; import { EventContext, ScopeId } from '@dolittle/sdk.events'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { guids } from '@dolittle/sdk.protobuf'; import { Cancellation } from '@dolittle/sdk.resilience'; import { IReverseCallClient, ReverseCallClient, reactiveDuplex } from '@dolittle/sdk.services'; @@ -25,7 +25,7 @@ export class EventFilterProcessor extends FilterEventProcessor Promise, pingTimeout: number, cancellation: Cancellation): IReverseCallClient { + protected createClient( + registerArguments: FilterRegistrationRequest, + callback: (request: FilterEventRequest, executionContext: ExecutionContext) => Promise, + pingTimeout: number, + cancellation: Cancellation): IReverseCallClient { return new ReverseCallClient ( (requests, cancellation) => reactiveDuplex(this._client, this._client.connect, requests, cancellation), FilterClientToRuntimeMessage, @@ -52,7 +56,7 @@ export class EventFilterProcessor extends FilterEventProcessor response.setCallcontext(context), (message) => message.getPing(), (message, pong) => message.setPong(pong), - this._executionContextManager, + this._executionContext, registerArguments, pingTimeout, callback, diff --git a/Source/events.filtering/Internal/FilterEventProcessor.ts b/Source/events.filtering/Internal/FilterEventProcessor.ts index b687b6de..64ac11db 100644 --- a/Source/events.filtering/Internal/FilterEventProcessor.ts +++ b/Source/events.filtering/Internal/FilterEventProcessor.ts @@ -8,6 +8,7 @@ import { IArtifacts } from '@dolittle/sdk.artifacts'; import { EventContext, EventSourceId } from '@dolittle/sdk.events'; import { EventProcessor } from '@dolittle/sdk.events.processing'; import { MissingEventInformation } from '@dolittle/sdk.events.handling'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { guids, executionContexts, artifacts } from '@dolittle/sdk.protobuf'; import { Failure } from '@dolittle/runtime.contracts/Fundamentals/Protobuf/Failure_pb'; @@ -35,7 +36,7 @@ export abstract class FilterEventProcessor extend return request.getRetryprocessingstate(); } - protected async handle(request: FilterEventRequest): Promise { + protected async handle(request: FilterEventRequest, executionContext: ExecutionContext): Promise { if (!request.getEvent()) { throw new MissingEventInformation('no event in FilterEventRequest'); } @@ -61,8 +62,7 @@ export abstract class FilterEventProcessor extend pbSequenceNumber, EventSourceId.from(guids.toSDK(pbEventSourceId)), DateTime.fromJSDate(pbOccurred.toDate()), - executionContexts.toSDK(pbExecutionContext) - ); + executionContext); let event = JSON.parse(pbEvent.getContent()); diff --git a/Source/events.filtering/Internal/PartitionedEventFilterProcessor.ts b/Source/events.filtering/Internal/PartitionedEventFilterProcessor.ts index aad2dc3a..c89d7c66 100644 --- a/Source/events.filtering/Internal/PartitionedEventFilterProcessor.ts +++ b/Source/events.filtering/Internal/PartitionedEventFilterProcessor.ts @@ -6,7 +6,7 @@ import { Logger } from 'winston'; import { Guid } from '@dolittle/rudiments'; import { IArtifacts } from '@dolittle/sdk.artifacts'; import { EventContext, ScopeId } from '@dolittle/sdk.events'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { guids } from '@dolittle/sdk.protobuf'; import { Cancellation } from '@dolittle/sdk.resilience'; import { IReverseCallClient, ReverseCallClient, reactiveDuplex } from '@dolittle/sdk.services'; @@ -26,7 +26,7 @@ export class PartitionedEventFilterProcessor extends FilterEventProcessor Promise, pingTimeout: number, cancellation: Cancellation): IReverseCallClient { + protected createClient( + registerArguments: PartitionedFilterRegistrationRequest, + callback: (request: FilterEventRequest, executionContext: ExecutionContext) => Promise, + pingTimeout: number, + cancellation: Cancellation): IReverseCallClient { return new ReverseCallClient ( (requests, cancellation) => reactiveDuplex(this._client, this._client.connectPartitioned, requests, cancellation), PartitionedFilterClientToRuntimeMessage, @@ -53,7 +57,7 @@ export class PartitionedEventFilterProcessor extends FilterEventProcessor response.setCallcontext(context), (message) => message.getPing(), (message, pong) => message.setPong(pong), - this._executionContextManager, + this._executionContext, registerArguments, pingTimeout, callback, diff --git a/Source/events.filtering/Internal/PublicEventFilterProcessor.ts b/Source/events.filtering/Internal/PublicEventFilterProcessor.ts index 3f8dad5f..39a1e030 100644 --- a/Source/events.filtering/Internal/PublicEventFilterProcessor.ts +++ b/Source/events.filtering/Internal/PublicEventFilterProcessor.ts @@ -6,7 +6,7 @@ import { Logger } from 'winston'; import { Guid } from '@dolittle/rudiments'; import { IArtifacts } from '@dolittle/sdk.artifacts'; import { EventContext } from '@dolittle/sdk.events'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { guids } from '@dolittle/sdk.protobuf'; import { Cancellation } from '@dolittle/sdk.resilience'; import { IReverseCallClient, ReverseCallClient, reactiveDuplex } from '@dolittle/sdk.services'; @@ -26,7 +26,7 @@ export class PublicEventFilterProcessor extends FilterEventProcessor Promise, pingTimeout: number, cancellation: Cancellation): IReverseCallClient { + protected createClient( + registerArguments: PublicFilterRegistrationRequest, + callback: (request: FilterEventRequest, executionContext: ExecutionContext) => Promise, + pingTimeout: number, + cancellation: Cancellation): IReverseCallClient { return new ReverseCallClient ( (requests, cancellation) => reactiveDuplex(this._client, this._client.connectPublic, requests, cancellation), PublicFilterClientToRuntimeMessage, @@ -52,7 +56,7 @@ export class PublicEventFilterProcessor extends FilterEventProcessor response.setCallcontext(context), (message) => message.getPing(), (message, pong) => message.setPong(pong), - this._executionContextManager, + this._executionContext, registerArguments, pingTimeout, callback, diff --git a/Source/events.filtering/PartitionedEventFilterBuilder.ts b/Source/events.filtering/PartitionedEventFilterBuilder.ts index e9be93a5..ef871859 100644 --- a/Source/events.filtering/PartitionedEventFilterBuilder.ts +++ b/Source/events.filtering/PartitionedEventFilterBuilder.ts @@ -5,7 +5,7 @@ import { Logger } from 'winston'; import { IArtifacts } from '@dolittle/sdk.artifacts'; import { ScopeId } from '@dolittle/sdk.events'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { FiltersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/Filters_grpc_pb'; @@ -53,7 +53,7 @@ export class PartitionedEventFilterBuilder { * @param {FilterId} filterId Unique identifier for the filter. * @param {ScopeId} scopeId The identifier of the scope the filter runs on. * @param {FiltersClient} client The client for working with the filters in the runtime. - * @param {IExecutionContextManager} executionContextManager Execution context manager for working with execution context. + * @param {ExecutionContext} executionContext Execution context. * @param {IArtifacts} artifacts Artifacts for identifying artifacts. * @param {Logger} logger Logger for logging. * @returns {IFilterProcessor} @@ -62,11 +62,11 @@ export class PartitionedEventFilterBuilder { filterId: FilterId, scopeId: ScopeId, client: FiltersClient, - executionContextManager: IExecutionContextManager, + executionContext: ExecutionContext, artifacts: IArtifacts, logger: Logger): IFilterProcessor { this.throwIfCallbackIsMissing(filterId, scopeId); - return new internal.PartitionedEventFilterProcessor(filterId, scopeId, this._callback!, client, executionContextManager, artifacts, logger); + return new internal.PartitionedEventFilterProcessor(filterId, scopeId, this._callback!, client, executionContext, artifacts, logger); } private throwIfCallbackIsMissing(filterId: FilterId, scopeId: ScopeId) { diff --git a/Source/events.filtering/PrivateEventFilterBuilder.ts b/Source/events.filtering/PrivateEventFilterBuilder.ts index 3f2aa6b2..104660bf 100644 --- a/Source/events.filtering/PrivateEventFilterBuilder.ts +++ b/Source/events.filtering/PrivateEventFilterBuilder.ts @@ -5,7 +5,7 @@ import { Logger } from 'winston'; import { IArtifacts } from '@dolittle/sdk.artifacts'; import { ScopeId } from '@dolittle/sdk.events'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { FiltersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/Filters_grpc_pb'; @@ -70,20 +70,20 @@ export class PrivateEventFilterBuilder { * Build an instance of a {@link IFilterProcessor}. * @param {FilterId} filterId Unique identifier for the filter. * @param {FiltersClient} client The client for working with the filters in the runtime. - * @param {IExecutionContextManager} executionContextManager Execution context manager for working with execution context. + * @param {ExecutionContext} executionContext Execution context manager for working with execution context. * @param {IArtifacts} artifacts Artifacts for identifying artifacts. * @param {Logger} logger Logger for logging. * @returns {IFilterProcessor} */ build( client: FiltersClient, - executionContextManager: IExecutionContextManager, + executionContext: ExecutionContext, artifacts: IArtifacts, logger: Logger): IFilterProcessor { if (!this._innerBuilder) { throw new FilterDefinitionIncomplete(this._filterId, 'call partitioned() or handle(...).'); } - return this._innerBuilder.build(this._filterId, this._scopeId, client, executionContextManager, artifacts, logger); + return this._innerBuilder.build(this._filterId, this._scopeId, client, executionContext, artifacts, logger); } } diff --git a/Source/events.filtering/PublicEventFilterBuilder.ts b/Source/events.filtering/PublicEventFilterBuilder.ts index 4a0ea546..f019b421 100644 --- a/Source/events.filtering/PublicEventFilterBuilder.ts +++ b/Source/events.filtering/PublicEventFilterBuilder.ts @@ -4,7 +4,7 @@ import { Logger } from 'winston'; import { IArtifacts } from '@dolittle/sdk.artifacts'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { ScopeId } from '@dolittle/sdk.events'; import { FiltersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/Filters_grpc_pb'; @@ -39,19 +39,19 @@ export class PublicEventFilterBuilder { * Build an instance of a {@link IFilterProcessor}. * @param {FilterId} filterId Unique identifier for the filter. * @param {FiltersClient} client The client for working with the filters in the runtime. - * @param {IExecutionContextManager} executionContextManager Execution context manager for working with execution context. + * @param {ExecutionContext} executionContext Execution context. * @param {IArtifacts} artifacts Artifacts for identifying artifacts. * @param {Logger} logger Logger for logging. * @returns {IFilterProcessor} */ build( client: FiltersClient, - executionContextManager: IExecutionContextManager, + executionContext: ExecutionContext, artifacts: IArtifacts, logger: Logger): IFilterProcessor { this.throwIfCallbackIsMissing(this._filterId); - return new internal.PublicEventFilterProcessor(this._filterId, this._callback!, client, executionContextManager, artifacts, logger); + return new internal.PublicEventFilterProcessor(this._filterId, this._callback!, client, executionContext, artifacts, logger); } private throwIfCallbackIsMissing(filterId: FilterId) { diff --git a/Source/events.filtering/UnpartitionedEventFilterBuilder.ts b/Source/events.filtering/UnpartitionedEventFilterBuilder.ts index c9b29c72..7b9191d2 100644 --- a/Source/events.filtering/UnpartitionedEventFilterBuilder.ts +++ b/Source/events.filtering/UnpartitionedEventFilterBuilder.ts @@ -5,7 +5,7 @@ import { Logger } from 'winston'; import { IArtifacts } from '@dolittle/sdk.artifacts'; import { ScopeId } from '@dolittle/sdk.events'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { FiltersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/Filters_grpc_pb'; @@ -33,7 +33,7 @@ export class UnpartitionedEventFilterBuilder { * Build an instance of a {@link IFilterProcessor}. * @param {FilterId} filterId Unique identifier for the filter. * @param {FiltersClient} client The client for working with the filters in the runtime. - * @param {IExecutionContextManager} executionContextManager Execution context manager for working with execution context. + * @param {ExecutionContext} executionContext Execution context. * @param {IArtifacts} artifacts Artifacts for identifying artifacts. * @param {Logger} logger Logger for logging. * @returns {IFilterProcessor} @@ -42,12 +42,12 @@ export class UnpartitionedEventFilterBuilder { filterId: FilterId, scopeId: ScopeId, client: FiltersClient, - executionContextManager: IExecutionContextManager, + executionContext: ExecutionContext, artifacts: IArtifacts, logger: Logger): IFilterProcessor { this.throwIfCallbackIsMissing(filterId, scopeId); - return new internal.EventFilterProcessor(filterId, scopeId, this._callback!, client, executionContextManager, artifacts, logger); + return new internal.EventFilterProcessor(filterId, scopeId, this._callback!, client, executionContext, artifacts, logger); } private throwIfCallbackIsMissing(filterId: FilterId, scopeId: ScopeId) { diff --git a/Source/events.handling/EventHandlers.ts b/Source/events.handling/EventHandlers.ts index fee8365b..e152c30b 100644 --- a/Source/events.handling/EventHandlers.ts +++ b/Source/events.handling/EventHandlers.ts @@ -7,7 +7,6 @@ import { Logger } from 'winston'; import { IArtifacts, ArtifactMap } from '@dolittle/sdk.artifacts'; import { IContainer } from '@dolittle/sdk.common'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; import { Cancellation, retryPipe } from '@dolittle/sdk.resilience'; import { EventHandlersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/EventHandlers_grpc_pb'; @@ -21,6 +20,7 @@ import { HandlesDecoratedMethods } from './HandlesDecoratedMethods'; import { EventHandlerSignature } from './EventHandlerSignature'; import { IEventHandler } from './IEventHandler'; import { ScopeId } from '@dolittle/sdk.events'; +import { ExecutionContext } from '@dolittle/sdk.execution'; class EventHandlerRegistration { constructor( @@ -41,7 +41,7 @@ export class EventHandlers implements IEventHandlers { * Initializes an instance of {@link EventHandlers}. * @param {EventHandlersClient} _eventHandlersClient Client to use for connecting to the runtime. * @param {IContainer} _container The container for creating instances needed. - * @param {IExecutionContextManager} _executionContextManager For managing execution context. + * @param {IExecutionContext} _executionContext The execution context. * @param {IArtifacts} _artifacts For mapping artifacts. * @param {Logger} _logger For logging. * @param {Cancellation} _cancellation For handling cancellation. @@ -49,7 +49,7 @@ export class EventHandlers implements IEventHandlers { constructor( private readonly _eventHandlersClient: EventHandlersClient, private readonly _container: IContainer, - private readonly _executionContextManager: IExecutionContextManager, + private readonly _executionContext: ExecutionContext, private readonly _artifacts: IArtifacts, private readonly _logger: Logger, private readonly _cancellation: Cancellation, @@ -115,7 +115,7 @@ export class EventHandlers implements IEventHandlers { eventHandler.partitioned, eventHandler, this._eventHandlersClient, - this._executionContextManager, + this._executionContext, this._artifacts, this._logger); this._logger.debug(`Registering a ${eventHandler.partitioned ? 'partitioned' : 'unpartitioned'} EventHandler with Id '${eventHandler.eventHandlerId}' for scope '${eventHandler.scopeId}'.`); diff --git a/Source/events.handling/EventHandlersBuilder.ts b/Source/events.handling/EventHandlersBuilder.ts index 56f03b1c..cfacc500 100644 --- a/Source/events.handling/EventHandlersBuilder.ts +++ b/Source/events.handling/EventHandlersBuilder.ts @@ -6,7 +6,6 @@ import { Logger } from 'winston'; import { IContainer } from '@dolittle/sdk.common'; import { Guid } from '@dolittle/rudiments'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; import { IArtifacts } from '@dolittle/sdk.artifacts'; import { Cancellation } from '@dolittle/sdk.resilience'; @@ -16,6 +15,7 @@ import { IEventHandlers } from './IEventHandlers'; import { EventHandlerId } from './EventHandlerId'; import { EventHandlerBuilder, EventHandlerBuilderCallback } from './EventHandlerBuilder'; import { EventHandlers } from './EventHandlers'; +import { ExecutionContext } from '@dolittle/sdk.execution'; export type EventHandlersBuilderCallback = (builder: EventHandlersBuilder) => void; @@ -44,11 +44,11 @@ export class EventHandlersBuilder { build( client: EventHandlersClient, container: IContainer, - executionContextManager: IExecutionContextManager, + executionContext: ExecutionContext, artifacts: IArtifacts, logger: Logger, cancellation: Cancellation): IEventHandlers { - const eventHandlers = new EventHandlers(client, container, executionContextManager, artifacts, logger, cancellation); + const eventHandlers = new EventHandlers(client, container, executionContext, artifacts, logger, cancellation); for (const [eventHandlerId, eventHandlerBuilder] of this._eventHandlers) { const eventHandler = eventHandlerBuilder.build(artifacts); diff --git a/Source/events.handling/Internal/EventHandlerProcessor.ts b/Source/events.handling/Internal/EventHandlerProcessor.ts index bb0bfe1a..bb7e583e 100644 --- a/Source/events.handling/Internal/EventHandlerProcessor.ts +++ b/Source/events.handling/Internal/EventHandlerProcessor.ts @@ -7,7 +7,7 @@ import { DateTime } from 'luxon'; import { IArtifacts } from '@dolittle/sdk.artifacts'; import { EventContext, ScopeId, EventSourceId } from '@dolittle/sdk.events'; import { EventProcessor } from '@dolittle/sdk.events.processing'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { Cancellation } from '@dolittle/sdk.resilience'; import { IReverseCallClient, ReverseCallClient, reactiveDuplex } from '@dolittle/sdk.services'; @@ -40,7 +40,7 @@ export class EventHandlerProcessor extends EventProcessor Promise, pingTimeout: number, cancellation: Cancellation): IReverseCallClient { + protected createClient( + registerArguments: EventHandlerRegistrationRequest, + callback: (request: HandleEventRequest, executionContext: ExecutionContext) => Promise, + pingTimeout: number, + cancellation: Cancellation): IReverseCallClient { return new ReverseCallClient ( (requests, cancellation) => reactiveDuplex(this._client, this._client.connect, requests, cancellation), EventHandlerClientToRuntimeMessage, @@ -84,7 +88,7 @@ export class EventHandlerProcessor extends EventProcessor response.setCallcontext(context), (message) => message.getPing(), (message, pong) => message.setPong(pong), - this._executionContextManager, + this._executionContext, registerArguments, pingTimeout, callback, @@ -107,7 +111,7 @@ export class EventHandlerProcessor extends EventProcessor { + protected async handle(request: HandleEventRequest, executionContext: ExecutionContext): Promise { if (!request.getEvent() || !request.getEvent()?.getEvent()) { throw new MissingEventInformation('no event in HandleEventRequest'); } @@ -133,8 +137,7 @@ export class EventHandlerProcessor extends EventProcessor /** @inheritdoc */ register(cancellation: Cancellation): Observable { - const client = this.createClient(this.registerArguments, (request: TRequest) => this.catchingHandle(request), this._pingTimeout, cancellation); + const client = this.createClient( + this.registerArguments, + (request: TRequest, executionContext: ExecutionContext) => this.catchingHandle(request, executionContext), + this._pingTimeout, + cancellation); return new Observable(subscriber => { this._logger.debug(`Registering ${this._kind} ${this._identifier} with the Runtime.`); client.subscribe({ @@ -66,7 +71,11 @@ export abstract class EventProcessor protected abstract get registerArguments (): TRegisterArguments; - protected abstract createClient (registerArguments: TRegisterArguments, callback: (request: TRequest) => Promise, pingTimeout: number, cancellation: Cancellation): IReverseCallClient; + protected abstract createClient ( + registerArguments: TRegisterArguments, + callback: (request: TRequest, executionContext: ExecutionContext) => Promise, + pingTimeout: number, + cancellation: Cancellation): IReverseCallClient; protected abstract getFailureFromRegisterResponse (response: TRegisterResponse): PbFailure | undefined; @@ -74,13 +83,13 @@ export abstract class EventProcessor protected abstract createResponseFromFailure (failure: ProcessorFailure): TResponse; - protected abstract handle (request: TRequest): Promise; + protected abstract handle (request: TRequest, executionContext: ExecutionContext): Promise; - private async catchingHandle(request: TRequest): Promise { + private async catchingHandle(request: TRequest, executionContext: ExecutionContext): Promise { let retryProcessingState: RetryProcessingState | undefined; try { retryProcessingState = this.getRetryProcessingStateFromRequest(request); - return await this.handle(request); + return await this.handle(request, executionContext); } catch (error) { const failure = new ProcessorFailure(); failure.setReason(`${error}`); diff --git a/Source/events/EventStore.ts b/Source/events/EventStore.ts index 8fdbdf24..282acbdc 100644 --- a/Source/events/EventStore.ts +++ b/Source/events/EventStore.ts @@ -6,7 +6,7 @@ import { map } from 'rxjs/operators'; import { callContexts, failures } from '@dolittle/sdk.protobuf'; import { ArtifactId, Artifact, IArtifacts } from '@dolittle/sdk.artifacts'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { Cancellation } from '@dolittle/sdk.resilience'; import { reactiveUnary } from '@dolittle/sdk.services'; @@ -30,13 +30,13 @@ export class EventStore implements IEventStore { * Initializes a new instance of {@link EventStore}. * @param {EventStoreClient} _eventStoreClient The client to use for connecting to the event store. * @param {IArtifacts} _artifacts Artifacts system for working with artifacts. - * @param {IExecutionContextManager} _executionContextManager For working with the execution context. + * @param {ExecutionContext} _executionContext The execution context. * @param {Logger} _logger Logger for logging. */ constructor( private _eventStoreClient: EventStoreClient, private _artifacts: IArtifacts, - private _executionContextManager: IExecutionContextManager, + private _executionContext: ExecutionContext, private _logger: Logger) { } @@ -70,7 +70,7 @@ export class EventStore implements IEventStore { !!event.public)); const request = new CommitEventsRequest(); - request.setCallcontext(callContexts.toProtobuf(this._executionContextManager.current)); + request.setCallcontext(callContexts.toProtobuf(this._executionContext)); request.setEventsList(uncommittedEvents); return reactiveUnary(this._eventStoreClient, this._eventStoreClient.commit, request, cancellation) diff --git a/Source/events/EventStoreBuilder.ts b/Source/events/EventStoreBuilder.ts index de89a85f..4c8247ed 100644 --- a/Source/events/EventStoreBuilder.ts +++ b/Source/events/EventStoreBuilder.ts @@ -1,16 +1,13 @@ // Copyright (c) Dolittle. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -import { ChannelCredentials } from 'grpc'; -import { ArtifactsBuilder, ArtifactsBuilderCallback, IArtifacts } from '@dolittle/sdk.artifacts'; -import { EventHandlersBuilder, EventHandlersBuilderCallback, IEventHandlers, eventHandler } from '@dolittle/sdk.events.handling'; -import { EventFiltersBuilder, EventFiltersBuilderCallback, IFilters } from '@dolittle/sdk.events.filtering'; -import { EventHandlersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/EventHandlers_grpc_pb'; -import { IContainer } from '@dolittle/sdk.common'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { IArtifacts } from '@dolittle/sdk.artifacts'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { Logger } from 'winston'; -import { Cancellation } from '@dolittle/sdk.resilience'; -import { FiltersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/Filters_grpc_pb'; +import { Guid } from '@dolittle/rudiments'; +import { EventStore } from './EventStore'; +import { EventStoreClient } from '@dolittle/runtime.contracts/Runtime/Events/EventStore_grpc_pb'; +import { IEventStore } from './IEventStore'; export type EventStoreBuilderCallback = (builder: EventStoreBuilder) => void; @@ -18,114 +15,24 @@ export type EventStoreBuilderCallback = (builder: EventStoreBuilder) => void; * Represents a builder for building event types, event handlers and event filters. */ export class EventStoreBuilder { - private _artifactsBuilder: ArtifactsBuilder = new ArtifactsBuilder(); - private _eventHandlersBuilder: EventHandlersBuilder = new EventHandlersBuilder(); - private _eventFiltersBuilder: EventFiltersBuilder = new EventFiltersBuilder(); + constructor( + private _eventStoreClient: EventStoreClient, + private _eventTypes: IArtifacts, + private _executionContext: ExecutionContext, + private _logger: Logger) { + } /** - * Configure event types through the artifacts builder. - * @param {ArtifactsBuilderCallback} callback The builder callback. - * @returns {ClientBuilder} The client builder for continuation. + * Build an {@link IEventStore} for the given tenant. + * + * @param {(Guid | string)} tenantId The tenant id. + * @returns {IEventStore} The event store. */ - withEventTypes(callback: ArtifactsBuilderCallback): EventStoreBuilder { - callback(this._artifactsBuilder); - return this; - } - - /** - * Configure event handlers through the event handlers builder. - * @param {EventHandlersBuilderCallback} callback The builder callback. - * @returns {ClientBuilder} The client builder for continuation. - */ - withEventHandlers(callback: EventHandlersBuilderCallback): EventStoreBuilder { - callback(this._eventHandlersBuilder); - return this; - } - - /** - * Configure event filters through the event filters builder. - * @param {EventFiltersBuilderCallback} callback The builder callback. - * @returns {ClientBuilder} The client builder for continuation. - */ - withFilters(callback: EventFiltersBuilderCallback): EventStoreBuilder { - callback(this._eventFiltersBuilder); - return this; - } - - /** - * Builds all artifacts, eventhandlers and filters and returns them as a tuple. - * @param {string} connectionString A string of 'host:port'. - * @param {ChannelCredentials} credentials grpc credentials. - * @param {IContainer} container An IoC container. - * @param {IExecutionContextManager} executionContextManager Execution context manager. - * @param {Logger} logger For logging. - * @param {Cancellation} cancellation A cancellation token. - */ - build( - connectionString: string, - credentials: ChannelCredentials, - container: IContainer, - executionContextManager: IExecutionContextManager, - logger: Logger, - cancellation: Cancellation): [IArtifacts, IEventHandlers, IFilters] { - const artifacts = this.buildEventTypes(); - - const eventHandlersClient = new EventHandlersClient(connectionString, credentials); - const eventHandlers = this.buildEventHandlers( - eventHandlersClient, - container, - executionContextManager, - artifacts, - logger, - cancellation - ); - - const filtersClient = new FiltersClient(connectionString, credentials); - const filters = this.buildFilters( - filtersClient, - executionContextManager, - artifacts, - logger, - cancellation - ); - return [artifacts, eventHandlers, filters]; - } - - /** - * Build an artifacts instance. - * @returns {IArtifacts} Artifacts to work with. - */ - private buildEventTypes() { - return this._artifactsBuilder.build(); - } - - /** - * Builds an instance for holding event handlers. - * @returns {IEventHandlers} New instance. - */ - private buildEventHandlers( - client: EventHandlersClient, - container: IContainer, - executionContextManager: IExecutionContextManager, - artifacts: IArtifacts, - logger: Logger, - cancellation: Cancellation): IEventHandlers { - return this._eventHandlersBuilder.build(client, container, executionContextManager, artifacts, logger, cancellation); - } - - /** - * Builds all the event filters. - * @param {FiltersClient} client The gRPC client for filters. - * @param {IExecutionContextManager} executionContextManager Execution context manager. - * @param {IArtifacts} artifacts For artifacts resolution. - * @param {Logger} logger For logging. - */ - private buildFilters( - client: FiltersClient, - executionContextManager: IExecutionContextManager, - artifacts: IArtifacts, - logger: Logger, - cancellation: Cancellation): IFilters { - return this._eventFiltersBuilder.build(client, executionContextManager, artifacts, logger, cancellation); + forTenant(tenantId: Guid | string): IEventStore { + return new EventStore( + this._eventStoreClient, + this._eventTypes, + this._executionContext.forTenant(tenantId), + this._logger); } } diff --git a/Source/execution/ExecutionContextExtensions.ts b/Source/execution/ExecutionContextExtensions.ts new file mode 100644 index 00000000..bbf99625 --- /dev/null +++ b/Source/execution/ExecutionContextExtensions.ts @@ -0,0 +1,43 @@ +// Copyright (c) Dolittle. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { Guid } from '@dolittle/rudiments'; +import { Claims } from './Claims'; +import { CorrelationId } from './CorrelationId'; +import { ExecutionContext } from './ExecutionContext'; +import { TenantId } from './TenantId'; + +declare module './index' { + interface ExecutionContext { + forTenant(tenantId: Guid | string): ExecutionContext; + forCorrelation(correlationId: Guid | string): ExecutionContext; + forClaims(claims: Claims): ExecutionContext; + } +} +ExecutionContext.prototype.forTenant = function (tenantId: Guid | string) { + return new ExecutionContext( + this.microserviceId, + TenantId.from(tenantId), + this.version, + this.environment, + this.correlationId, + this.claims); +}; +ExecutionContext.prototype.forCorrelation = function (correlationId: Guid | string) { + return new ExecutionContext( + this.microserviceId, + this.tenantId, + this.version, + this.environment, + CorrelationId.from(correlationId), + this.claims); +}; +ExecutionContext.prototype.forClaims = function (claims: Claims) { + return new ExecutionContext( + this.microserviceId, + this.tenantId, + this.version, + this.environment, + this.correlationId, + claims); +}; \ No newline at end of file diff --git a/Source/execution/ExecutionContextManager.ts b/Source/execution/ExecutionContextManager.ts deleted file mode 100644 index 64a92a1d..00000000 --- a/Source/execution/ExecutionContextManager.ts +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) Dolittle. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -import async_hooks from 'async_hooks'; -import { Claims } from './Claims'; -import { IExecutionContextManager } from './IExecutionContextManager'; -import { MicroserviceId } from './MicroserviceId'; -import { Version } from './Version'; -import { ExecutionContext } from './ExecutionContext'; -import { TenantId } from './TenantId'; -import { CorrelationId } from './CorrelationId'; -import { Environment } from './Environment'; - - -/** - * Represents an implementation of {@link IExecutionContextManager}. - */ -export class ExecutionContextManager implements IExecutionContextManager { - private _executionContextByAsyncId: Map = new Map(); - private _base: ExecutionContext; - - /** - * Initializes a new instance of {@link IExecutionContextManager}. - * @param {MicroserviceId} microserviceId The unique identifier of the microservice. - * @param {Version} version The version of the currently running software. - * @param {string} environment The environment the software is running in. (e.g. development, production). - */ - constructor(private _microserviceId: MicroserviceId, private _version: Version, private _environment: Environment) { - this._base = new ExecutionContext(_microserviceId, TenantId.system, _version, _environment, CorrelationId.system, Claims.empty); - - async_hooks.createHook({ - init: this.asyncOperationInit.bind(this), - destroy: this.asyncOperationDestroy.bind(this) - }).enable(); - } - - /** @inheritdoc */ - get current(): ExecutionContext { - const asyncId = async_hooks.executionAsyncId(); - let executionContext = this._executionContextByAsyncId.get(asyncId); - if (!executionContext) { - executionContext = new ExecutionContext( - this._microserviceId, - this._base.tenantId, - this._version, - this._environment, - CorrelationId.new(), - this._base.claims - ); - this._executionContextByAsyncId.set(asyncId, executionContext); - } - return executionContext; - } - - /** @inheritdoc */ - forTenant(tenantId: TenantId | string, claims?: Claims): ExecutionContextManager { - const asyncId = async_hooks.executionAsyncId(); - const current = this.current; - const executionContext = new ExecutionContext( - current.microserviceId, - TenantId.from(tenantId), - current.version, - current.environment, - current.correlationId, - claims ?? this._base.claims - ); - - this._executionContextByAsyncId.set(asyncId, executionContext); - return this; - } - - private asyncOperationInit(asyncId: number, type: string, triggerAsyncId: number, resource: object): void { - let parent: ExecutionContext; - - if (this._executionContextByAsyncId.has(triggerAsyncId)) { - parent = this._executionContextByAsyncId.get(triggerAsyncId) || this._base; - } else { - parent = this._base; - } - - const executionContext = new ExecutionContext( - this._microserviceId, - parent.tenantId, - this._version, - this._environment, - CorrelationId.new(), - parent.claims - ); - - this._executionContextByAsyncId.set(asyncId, executionContext); - } - - private asyncOperationDestroy(asyncId: number): void { - if (this._executionContextByAsyncId.has(asyncId)) { - this._executionContextByAsyncId.delete(asyncId); - } - } -} diff --git a/Source/execution/IExecutionContextManager.ts b/Source/execution/IExecutionContextManager.ts deleted file mode 100644 index 6dd3ac88..00000000 --- a/Source/execution/IExecutionContextManager.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Dolittle. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -import { ExecutionContextManager } from './ExecutionContextManager'; -import { ExecutionContext } from './ExecutionContext'; -import { TenantId } from './TenantId'; -import { Claims } from './Claims'; -import { Guid } from '@dolittle/rudiments'; - -/** - * Defines a manager for working with the {@link ExecutionContext}. - */ -export interface IExecutionContextManager { - /** - * Gets the current execution context - */ - readonly current: ExecutionContext; - - /** - * Set the current execution context for a tenant and possibly claims. - * @param {TenantId | string} tenantId Tenant to set for. - * @param {Claims} [claims] Optional claims to set for. - * @returns {ExecutionContext} The execution context that was set. - */ - forTenant(tenantId: string | Guid | TenantId, claims?: Claims): ExecutionContextManager; -} diff --git a/Source/execution/for_ExecutionContextManager/when_getting_context_from_two_different_nested_async_contexts.ts b/Source/execution/for_ExecutionContextManager/when_getting_context_from_two_different_nested_async_contexts.ts deleted file mode 100644 index 2c404ede..00000000 --- a/Source/execution/for_ExecutionContextManager/when_getting_context_from_two_different_nested_async_contexts.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Dolittle. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -import { ExecutionContextManager, Version, TenantId, MicroserviceId, ExecutionContext, Environment } from '../index'; - - -describe('when getting context from two different nested async contexts', async () => { - const microserviceId = MicroserviceId.from('c87b335d-be3b-48ca-87c6-f6df2c3939a2'); - const version = new Version(1, 0, 0, 0); - const environment = Environment.development; - const firstLevelTenant = TenantId.from('941b5d80-1fdd-4f1e-996f-dc1126338f3d'); - const secondLevelTenant = TenantId.from('11850573-b164-4835-8398-d1a48d9bb9be'); - - const executionContextManager = new ExecutionContextManager(microserviceId, version, environment); - - const base = executionContextManager.current; - let firstLevel: ExecutionContext; - let secondLevel: ExecutionContext; - - before(() => { - const promise = new Promise((resolve) => { - setTimeout(() => { - executionContextManager.forTenant(firstLevelTenant); - firstLevel = executionContextManager.current; - - setTimeout(() => { - executionContextManager.forTenant(secondLevelTenant); - secondLevel = executionContextManager.current; - - resolve(); - }); - }, 1); - }); - - return promise; - }); - - it('should have first level be different from base', () => firstLevel.should.not.equal(base)); - it('should have first level correlation id be different from base', () => firstLevel.correlationId.should.not.equal(base.correlationId)); - it('should set tenant for first level', () => firstLevel.tenantId.should.equal(firstLevelTenant)); - it('should have second level be different from first level', () => secondLevel.should.not.equal(firstLevel)); - it('should have second level correlation id be different from first levels', () => secondLevel.correlationId.should.not.equal(firstLevel.correlationId)); - it('should set tenant for second level', () => secondLevel.tenantId.should.equal(secondLevelTenant)); -}); diff --git a/Source/execution/index.ts b/Source/execution/index.ts index 10dedea0..e50c262f 100644 --- a/Source/execution/index.ts +++ b/Source/execution/index.ts @@ -9,6 +9,6 @@ export { TenantId } from './TenantId'; export { Claim } from './Claim'; export { Claims } from './Claims'; export { ExecutionContext } from './ExecutionContext'; -export { ExecutionContextManager } from './ExecutionContextManager'; -export { IExecutionContextManager } from './IExecutionContextManager'; export { Version } from './Version'; + +import './ExecutionContextExtensions'; diff --git a/Source/sdk/Client.ts b/Source/sdk/Client.ts index 6695a03d..e4c9877f 100644 --- a/Source/sdk/Client.ts +++ b/Source/sdk/Client.ts @@ -4,18 +4,20 @@ import grpc from 'grpc'; import { Logger} from 'winston'; -import { IArtifacts } from '@dolittle/sdk.artifacts'; +import { ArtifactsBuilder, ArtifactsBuilderCallback, IArtifacts } from '@dolittle/sdk.artifacts'; import { IContainer, Container } from '@dolittle/sdk.common'; -import { IEventStore, EventStore, EventStoreBuilderCallback, EventStoreBuilder } from '@dolittle/sdk.events'; -import { IFilters } from '@dolittle/sdk.events.filtering'; -import { IEventHandlers } from '@dolittle/sdk.events.handling'; -import { IExecutionContextManager, MicroserviceId, ExecutionContextManager, Environment, MicroserviceBuilder, MicroserviceBuilderCallback } from '@dolittle/sdk.execution'; +import { EventStoreBuilder } from '@dolittle/sdk.events'; +import { EventFiltersBuilder, EventFiltersBuilderCallback, IFilters } from '@dolittle/sdk.events.filtering'; +import { EventHandlersBuilder, EventHandlersBuilderCallback, IEventHandlers } from '@dolittle/sdk.events.handling'; +import { MicroserviceId, Environment, MicroserviceBuilder, MicroserviceBuilderCallback, ExecutionContext, TenantId, CorrelationId, Claims } from '@dolittle/sdk.execution'; import { EventHorizonsBuilder, EventHorizonsBuilderCallback, IEventHorizons } from '@dolittle/sdk.eventhorizon'; import { Cancellation } from '@dolittle/sdk.resilience'; import { EventStoreClient } from '@dolittle/runtime.contracts/Runtime/Events/EventStore_grpc_pb'; import { SubscriptionsClient } from '@dolittle/runtime.contracts/Runtime/EventHorizon/Subscriptions_grpc_pb'; import { LoggingBuilder, LoggingBuilderCallback } from './LoggingBuilder'; +import { EventHandlersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/EventHandlers_grpc_pb'; +import { FiltersClient } from '@dolittle/runtime.contracts/Runtime/Events.Processing/Filters_grpc_pb'; /** @@ -26,18 +28,16 @@ export class Client { /** * Creates an instance of client. * @param {Logger} logger Winston Logger for logging. - * @param {IExecutionContextManager} executionContextManager The execution context manager. * @param {IArtifacts} artifacts All the configured artifacts. - * @param {IEventStore} eventStore The event store to work with. + * @param {EventStoreBuilder} eventStore The event store builder to work with. * @param {IEventHandlers} eventHandlers All the event handlers. * @param {IFilters} filters All the filters. * @param {IEventHorizons} eventHorizons All event horizons. */ constructor( readonly logger: Logger, - readonly executionContextManager: IExecutionContextManager, readonly artifacts: IArtifacts, - readonly eventStore: IEventStore, + readonly eventStore: EventStoreBuilder, readonly eventHandlers: IEventHandlers, readonly filters: IFilters, readonly eventHorizons: IEventHorizons) { @@ -63,11 +63,13 @@ export class ClientBuilder { private _port = 50053; private _environment: Environment = Environment.undetermined; private _microserviceBuilder: MicroserviceBuilder; - private _eventHorizonsBuilder: EventHorizonsBuilder; + private readonly _eventHorizonsBuilder: EventHorizonsBuilder; + private readonly _eventTypesBuilder: ArtifactsBuilder; + private readonly _eventHandlersBuilder: EventHandlersBuilder; + private readonly _filtersBuilder: EventFiltersBuilder; private _cancellation: Cancellation; private _loggingBuilder: LoggingBuilder; private _container: IContainer = new Container(); - private _eventStoreBuilder: EventStoreBuilder; /** * Creates an instance of client builder. @@ -77,7 +79,9 @@ export class ClientBuilder { this._eventHorizonsBuilder = new EventHorizonsBuilder(); this._cancellation = Cancellation.default; this._loggingBuilder = new LoggingBuilder(); - this._eventStoreBuilder = new EventStoreBuilder(); + this._eventTypesBuilder = new ArtifactsBuilder(); + this._eventHandlersBuilder = new EventHandlersBuilder(); + this._filtersBuilder = new EventFiltersBuilder(); } /** @@ -115,15 +119,39 @@ export class ClientBuilder { } /** - * Configure event types, event handlers and event filters. - * @param {EventStoreBuilderCallback} callback The builder callback. + * Configure event types. + * + * @param {ArtifactsBuilderCallback} callback The builder callback * @returns {ClientBuilder} The client builder for continuation. */ - withEventStore(callback: EventStoreBuilderCallback): ClientBuilder { - callback(this._eventStoreBuilder); + withEventTypes(callback: ArtifactsBuilderCallback): ClientBuilder { + callback(this._eventTypesBuilder); return this; } + /** + * Configure the event handlers. + * + * @param {EventHandlersBuilderCallback} callback The builder callback. + * @returns {ClientBuilder} The client builder for continuation. + */ + withEventHandlers(callback: EventHandlersBuilderCallback): ClientBuilder { + callback(this._eventHandlersBuilder); + return this; + } + + /** + * Configure the event filters. + * + * @param {EventFiltersBuilderCallback} callback The builder callback. + * @returns {ClientBuilder} The client builder for continuation. + */ + withFilters(callback: EventFiltersBuilderCallback): ClientBuilder { + callback(this._filtersBuilder); + return this; + } + + /** * Connect to a specific host and port for the Dolittle runtime. * @param {string} host The host name to connect to. @@ -176,29 +204,43 @@ export class ClientBuilder { const logger = this._loggingBuilder.build(microserviceId); const connectionString = `${this._host}:${this._port}`; const credentials = grpc.credentials.createInsecure(); - const executionContextManager = new ExecutionContextManager(microserviceId, version, this._environment); - - const [artifacts, eventHandlers, filters] = this._eventStoreBuilder.build( - connectionString, - credentials, + const executionContext = new ExecutionContext( + microserviceId, + TenantId.system, + version, + this._environment, + CorrelationId.system, + Claims.empty); + + const eventTypes = this._eventTypesBuilder.build(); + + const eventStoreBuilder = new EventStoreBuilder( + new EventStoreClient(connectionString, credentials), + eventTypes, + executionContext, + logger); + const eventHandlers = this._eventHandlersBuilder.build( + new EventHandlersClient(connectionString, credentials), this._container, - executionContextManager, + executionContext, + eventTypes, logger, - this._cancellation - ); + this._cancellation); + + const filters = this._filtersBuilder.build( + new FiltersClient(connectionString, credentials), + executionContext, + eventTypes, + logger, + this._cancellation); const subscriptionsClient = new SubscriptionsClient(connectionString, credentials); - const eventHorizons = this._eventHorizonsBuilder.build(subscriptionsClient, executionContextManager, logger); + const eventHorizons = this._eventHorizonsBuilder.build(subscriptionsClient, executionContext, logger); return new Client( logger, - executionContextManager, - artifacts, - new EventStore( - new EventStoreClient(connectionString, credentials), - artifacts, - executionContextManager, - logger), + eventTypes, + eventStoreBuilder, eventHandlers, filters, eventHorizons diff --git a/Source/sdk/LoggingBuilder.ts b/Source/sdk/LoggingBuilder.ts index 52bfda5e..b3272470 100644 --- a/Source/sdk/LoggingBuilder.ts +++ b/Source/sdk/LoggingBuilder.ts @@ -34,7 +34,7 @@ export class LoggingBuilder { /** * Builds the configured logger. - * @param microserviceId Sets the {@linkMicroserviceId} in the defaultMeta in winston. + * @param microserviceId Sets the {@link MicroserviceId} in the defaultMeta in winston. */ build(microserviceId: MicroserviceId) { if (!this._options.defaultMeta.microserviceId) { diff --git a/Source/services/IReverseCallClient.ts b/Source/services/IReverseCallClient.ts index ef89e0d8..4ce9b8c7 100644 --- a/Source/services/IReverseCallClient.ts +++ b/Source/services/IReverseCallClient.ts @@ -1,9 +1,10 @@ // Copyright (c) Dolittle. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +import { ExecutionContext } from '@dolittle/sdk.execution'; import { Subscribable } from 'rxjs'; -export type ReverseCallCallback = (request: TRequest) => TResponse | Promise; +export type ReverseCallCallback = (request: TRequest, executionContext: ExecutionContext) => TResponse | Promise; /** * Defines a client for reverse calls coming from the server to the client. diff --git a/Source/services/ReverseCallClient.ts b/Source/services/ReverseCallClient.ts index 0b78f32b..5eec0612 100644 --- a/Source/services/ReverseCallClient.ts +++ b/Source/services/ReverseCallClient.ts @@ -11,7 +11,7 @@ import { ReverseCallRequestContext, ReverseCallResponseContext, ReverseCallArgum import { Ping, Pong } from '@dolittle/runtime.contracts/Fundamentals/Services/Ping_pb'; import { Guid } from '@dolittle/rudiments'; -import { IExecutionContextManager } from '@dolittle/sdk.execution'; +import { ExecutionContext } from '@dolittle/sdk.execution'; import { executionContexts, guids } from '@dolittle/sdk.protobuf'; import { Cancellation } from '@dolittle/sdk.resilience'; @@ -37,7 +37,7 @@ export class ReverseCallClient void, private _getMessagePing: (message: TServerMessage) => Ping | undefined, private _setMessagePong: (message: TClientMessage, pong: Pong) => void, - private _executionContextManager: IExecutionContextManager, + private _executionContext: ExecutionContext, private _connectArguments: TConnectArguments, private _pingInterval: number, private _callback: ReverseCallCallback, @@ -67,7 +67,7 @@ export class ReverseCallClient Date: Mon, 28 Sep 2020 20:21:17 +0200 Subject: [PATCH 2/5] Cleanup sample. Make it pass tests --- Samples/Basic/index.ts | 23 +++++++++++----------- Source/execution/for_Dummy/when_nothing.ts | 6 ++++++ 2 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 Source/execution/for_Dummy/when_nothing.ts diff --git a/Samples/Basic/index.ts b/Samples/Basic/index.ts index 9b2f2277..4f0a78bb 100644 --- a/Samples/Basic/index.ts +++ b/Samples/Basic/index.ts @@ -21,22 +21,21 @@ const client = Client .forMicroservice('7a6155dd-9109-4488-8f6f-c57fe4b65bfb', microservice => { microservice.withVersion(Version.first); }) - .withFilters(filterBuilder => { - filterBuilder.createPrivateFilter('79e12ab3-2751-47e1-b959-d898dc4d6ee8', fb => { - fb - .handle((event: any, context: EventContext) => { + .withFilters(filterBuilder => + filterBuilder + .createPrivateFilter('79e12ab3-2751-47e1-b959-d898dc4d6ee8', fb => + fb.handle((event: any, context: EventContext) => { return new Promise((resolve, reject) => { console.log('Filtering event', event); }); - }); - }); - filterBuilder.createPublicFilter('2c087657-b318-40b1-ae92-a400de44e507', fb => { - fb - .handle((event: any, context: EventContext) => { + }) + ) + .createPublicFilter('2c087657-b318-40b1-ae92-a400de44e507', fb => + fb.handle((event: any, context: EventContext) => { return new PartitionedFilterResult(true, PartitionId.unspecified); - }); - }); - }) + }) + ) + ) .build(); diff --git a/Source/execution/for_Dummy/when_nothing.ts b/Source/execution/for_Dummy/when_nothing.ts new file mode 100644 index 00000000..1e7877bf --- /dev/null +++ b/Source/execution/for_Dummy/when_nothing.ts @@ -0,0 +1,6 @@ +// Copyright (c) Dolittle. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +describe('when nothing', () => { + it('should be fine', () => true.should.be.true); +}); From 0eac6cf2fa306b437d9f54700531ebf9f597d032 Mon Sep 17 00:00:00 2001 From: Sindre Alstad Wilting Date: Wed, 30 Sep 2020 11:10:56 +0200 Subject: [PATCH 3/5] Update Source/events/EventStoreBuilder.ts Co-authored-by: Joel Hoisko --- Source/events/EventStoreBuilder.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/events/EventStoreBuilder.ts b/Source/events/EventStoreBuilder.ts index 4c8247ed..de1c3f25 100644 --- a/Source/events/EventStoreBuilder.ts +++ b/Source/events/EventStoreBuilder.ts @@ -9,8 +9,6 @@ import { EventStore } from './EventStore'; import { EventStoreClient } from '@dolittle/runtime.contracts/Runtime/Events/EventStore_grpc_pb'; import { IEventStore } from './IEventStore'; -export type EventStoreBuilderCallback = (builder: EventStoreBuilder) => void; - /** * Represents a builder for building event types, event handlers and event filters. */ From 8dca3e559c6a5652041a904f6a51f1020b298e0b Mon Sep 17 00:00:00 2001 From: Sindre Alstad Wilting Date: Wed, 30 Sep 2020 11:11:07 +0200 Subject: [PATCH 4/5] Update Source/events/EventStoreBuilder.ts Co-authored-by: Joel Hoisko --- Source/events/EventStoreBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/events/EventStoreBuilder.ts b/Source/events/EventStoreBuilder.ts index de1c3f25..50b6d85a 100644 --- a/Source/events/EventStoreBuilder.ts +++ b/Source/events/EventStoreBuilder.ts @@ -10,7 +10,7 @@ import { EventStoreClient } from '@dolittle/runtime.contracts/Runtime/Events/Eve import { IEventStore } from './IEventStore'; /** - * Represents a builder for building event types, event handlers and event filters. + * Represents a builder for building an event store. */ export class EventStoreBuilder { From 92f9d4efd56afaaf431f809c22f21a25ec054337 Mon Sep 17 00:00:00 2001 From: Sindre Wilting Date: Wed, 30 Sep 2020 11:14:55 +0200 Subject: [PATCH 5/5] Make it build --- Source/events/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/events/index.ts b/Source/events/index.ts index 9410e803..bae54548 100644 --- a/Source/events/index.ts +++ b/Source/events/index.ts @@ -18,4 +18,4 @@ export { CommitEventsResponse } from './CommitEventsResponse'; export { EventConverters } from './EventConverters'; export { IEventStore } from './IEventStore'; export { UncommittedEvent } from './UncommittedEvent'; -export { EventStoreBuilder, EventStoreBuilderCallback } from './EventStoreBuilder'; +export { EventStoreBuilder } from './EventStoreBuilder';