-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[EPH] Call methods on PartitionProcessor while processing single part…
…ition (#4467) * [EPH] Call methods on PartitionProcessor while processing single partition
- Loading branch information
1 parent
7d9c275
commit 3d1475c
Showing
7 changed files
with
339 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { | ||
EventHubClient, | ||
EventData, | ||
EventPosition, | ||
delay, | ||
EventProcessor, | ||
PartitionContext | ||
} from "@azure/event-hubs"; | ||
|
||
class SimplePartitionProcessor { | ||
private _context: PartitionContext; | ||
constructor(context: PartitionContext) { | ||
this._context = context; | ||
} | ||
async processEvents(events: EventData[]) { | ||
for (const event of events) { | ||
console.log( | ||
"Received event: '%s' from partition: '%s' and consumer group: '%s'", | ||
event.body, | ||
this._context.partitionId, | ||
this._context.consumerGroupName | ||
); | ||
} | ||
} | ||
|
||
async processError(error: Error) { | ||
console.log(`Encountered an error: ${error.message}`); | ||
} | ||
|
||
async initialize() { | ||
console.log(`Started processing`); | ||
} | ||
|
||
async close() { | ||
console.log(`Stopped processing`); | ||
} | ||
} | ||
|
||
// Define connection string and related Event Hubs entity name here | ||
const connectionString = ""; | ||
const eventHubName = ""; | ||
|
||
async function main() { | ||
const client = new EventHubClient(connectionString, eventHubName); | ||
|
||
const eventProcessorFactory = (context: PartitionContext) => { | ||
return new SimplePartitionProcessor(context); | ||
}; | ||
|
||
const processor = new EventProcessor( | ||
EventHubClient.defaultConsumerGroupName, | ||
client, | ||
eventProcessorFactory, | ||
"partitionManager" as any, | ||
{ | ||
initialEventPosition: EventPosition.earliest(), | ||
maxBatchSize: 10, | ||
maxWaitTimeInSeconds: 20 | ||
} | ||
); | ||
await processor.start(); | ||
// after 2 seconds, stop processing | ||
await delay(2000); | ||
|
||
await processor.stop(); | ||
await client.close(); | ||
} | ||
|
||
main().catch((err) => { | ||
console.log("Error occurred: ", err); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as log from "./log"; | ||
import { EventProcessorOptions, PartitionProcessor } from "./eventProcessor"; | ||
import { PartitionContext } from "./partitionContext"; | ||
import { EventHubClient } from "./eventHubClient"; | ||
import { EventPosition } from "./eventPosition"; | ||
import { EventHubConsumer } from "./receiver"; | ||
import { AbortController } from "@azure/abort-controller"; | ||
|
||
export class PartitionPump { | ||
private _partitionContext: PartitionContext; | ||
private _eventHubClient: EventHubClient; | ||
private _partitionProcessor: PartitionProcessor; | ||
private _processorOptions: EventProcessorOptions; | ||
private _receiver: EventHubConsumer | undefined; | ||
private _isReceiving: boolean = false; | ||
private _abortController: AbortController; | ||
|
||
constructor( | ||
eventHubClient: EventHubClient, | ||
partitionContext: PartitionContext, | ||
partitionProcessor: PartitionProcessor, | ||
options?: EventProcessorOptions | ||
) { | ||
if (!options) options = {}; | ||
this._eventHubClient = eventHubClient; | ||
this._partitionContext = partitionContext; | ||
this._partitionProcessor = partitionProcessor; | ||
this._processorOptions = options; | ||
this._abortController = new AbortController(); | ||
} | ||
|
||
async start(partitionId: string): Promise<void> { | ||
if (this._partitionProcessor.initialize) { | ||
await this._partitionProcessor.initialize(); | ||
} | ||
this._receiveEvents(partitionId); | ||
log.partitionPump("Successfully started the receiver."); | ||
} | ||
|
||
private async _receiveEvents(partitionId: string): Promise<void> { | ||
this._isReceiving = true; | ||
try { | ||
this._receiver = await this._eventHubClient.createConsumer( | ||
this._partitionContext.consumerGroupName, | ||
partitionId, | ||
this._processorOptions.initialEventPosition || EventPosition.earliest() | ||
); | ||
|
||
while (this._isReceiving) { | ||
const receivedEvents = await this._receiver.receiveBatch( | ||
this._processorOptions.maxBatchSize || 1, | ||
this._processorOptions.maxWaitTimeInSeconds, | ||
this._abortController.signal | ||
); | ||
await this._partitionProcessor.processEvents(receivedEvents); | ||
} | ||
} catch (err) { | ||
this._isReceiving = false; | ||
try { | ||
if (this._receiver) { | ||
await this._receiver.close(); | ||
} | ||
await this._partitionProcessor.processError(err); | ||
log.error("An error occurred while receiving events.", err); | ||
} catch (err) { | ||
log.error("An error occurred while closing the receiver", err); | ||
} | ||
} | ||
} | ||
|
||
async stop(reason: string): Promise<void> { | ||
this._isReceiving = false; | ||
try { | ||
if (this._receiver) { | ||
await this._receiver.close(); | ||
} | ||
this._abortController.abort(); | ||
if (this._partitionProcessor.close) { | ||
await this._partitionProcessor.close(reason); | ||
} | ||
} catch (err) { | ||
log.error("An error occurred while closing the receiver.", err); | ||
throw err; | ||
} | ||
} | ||
} |
Oops, something went wrong.