![]() |
VOOZH | about |
dotnet add package F88.Camunda.Orchestrator.Library --version 3.0.0
NuGet\Install-Package F88.Camunda.Orchestrator.Library -Version 3.0.0
<PackageReference Include="F88.Camunda.Orchestrator.Library" Version="3.0.0" />
<PackageVersion Include="F88.Camunda.Orchestrator.Library" Version="3.0.0" />Directory.Packages.props
<PackageReference Include="F88.Camunda.Orchestrator.Library" />Project file
paket add F88.Camunda.Orchestrator.Library --version 3.0.0
#r "nuget: F88.Camunda.Orchestrator.Library, 3.0.0"
#:package F88.Camunda.Orchestrator.Library@3.0.0
#addin nuget:?package=F88.Camunda.Orchestrator.Library&version=3.0.0Install as a Cake Addin
#tool nuget:?package=F88.Camunda.Orchestrator.Library&version=3.0.0Install as a Cake Tool
Copy các file sau từ bin/Release/net8.0/ vào project đích:
Orchestrator.Library.dllOrchestrator.Library.deps.json (nếu cần)<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Reference Include="Orchestrator.Library">
<HintPath>lib\Orchestrator.Library.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Orchestrator.Library\Orchestrator.Library.csproj" />
</ItemGroup>
</Project>
using Orchestrator.Library.Services;
using Orchestrator.Library.Workers;
using Orchestrator.Library.Models;
using Orchestrator.Library.Exceptions;
dotnet pack --configuration Release
dotnet add package Orchestrator.Library --version 1.0.0
Hoặc thêm vào .csproj:
<ItemGroup>
<PackageReference Include="Orchestrator.Library" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Orchestrator.Library\Orchestrator.Library.csproj" />
</ItemGroup>
// Program.cs
using Orchestrator.Library.Services;
using Orchestrator.Library.Models;
var builder = WebApplication.CreateBuilder();
// Đăng ký ZeebeService
builder.Services.AddZeebeService(provider =>
{
var configuration = provider.GetRequiredService<IConfiguration>();
var zeebeUrl = configuration["Zeebe:GatewayAddress"] ?? "localhost:26500";
return ZeebeClient.Builder()
.UseGatewayAddress(zeebeUrl)
.UsePlainText()
.Build();
});
// Đăng ký Kafka configuration
builder.Services.Configure<BaseConfigKafka>(builder.Configuration.GetSection("Kafka"));
// Đăng ký KafkaMessageService
builder.Services.AddSingleton<IKafkaMessageService, KafkaMessageService>();
// Đăng ký workers
builder.Services.AddWorker<MyWorker, MyJobProcessor, MyJobData>();
var app = builder.Build();
app.Run();
// Program.cs
using Orchestrator.Library.Services;
using Microsoft.Extensions.Hosting;
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
// Đăng ký ZeebeService
services.AddZeebeService(provider =>
{
var configuration = provider.GetRequiredService<IConfiguration>();
var zeebeUrl = configuration["Zeebe:GatewayAddress"] ?? "localhost:26500";
return ZeebeClient.Builder()
.UseGatewayAddress(zeebeUrl)
.UsePlainText()
.Build();
});
// Đăng ký Kafka configuration
services.Configure<BaseConfigKafka>(context.Configuration.GetSection("Kafka"));
// Đăng ký KafkaMessageService
services.AddSingleton<IKafkaMessageService, KafkaMessageService>();
// Đăng ký workers
services.AddWorker<MyWorker, MyJobProcessor, MyJobData>();
// Đăng ký hosted services
services.AddHostedService<MyWorkerHostedService>();
})
.Build();
host.Run();
<ItemGroup>
<PackageReference Include="Zeebe.Client" Version="8.3.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Confluent.Kafka" Version="2.3.0" />
</ItemGroup>
// MyJobData.cs
namespace MyProject.Models;
public class MyJobData
{
public string Message { get; set; } = string.Empty;
public int Priority { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
// MyJobProcessor.cs
using Orchestrator.Library.Services;
using Orchestrator.Library.Workers;
using Orchestrator.Library.Exceptions;
using MyProject.Models;
namespace MyProject.Workers;
public class MyJobProcessor : IJobProcessor<MyJobData>
{
private readonly IZeebeService _zeebeService;
private readonly ILogger<MyJobProcessor> _logger;
public MyJobProcessor(IZeebeService zeebeService, ILogger<MyJobProcessor> logger)
{
_zeebeService = zeebeService;
_logger = logger;
}
public async Task ProcessJobAsync(IJobClient jobClient, IJob job, MyJobData data, CancellationToken stoppingToken)
{
try
{
_logger.LogInformation("Processing job. JobKey: {JobKey}, Message: {Message}",
job.Key, data.Message);
// Xử lý business logic
var result = await ProcessBusinessLogic(data);
// Complete job
await _zeebeService.CompleteJobAsync(jobClient, job.Key, result);
// Publish message
await _zeebeService.PublishMessageAsync(
"job-completed",
$"job-{job.Key}",
new { JobKey = job.Key, Result = result }
);
_logger.LogInformation("Job completed successfully. JobKey: {JobKey}", job.Key);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing job. JobKey: {JobKey}", job.Key);
await _zeebeService.ThrowErrorAsync(jobClient, job.Key, "PROCESSING_ERROR", ex.Message);
}
}
private async Task<object> ProcessBusinessLogic(MyJobData data)
{
// Implement your business logic here
await Task.Delay(1000); // Simulate processing
return new {
Success = true,
ProcessedMessage = data.Message.ToUpper(),
ProcessedAt = DateTime.UtcNow
};
}
}
// MyWorker.cs
using Orchestrator.Library.Workers;
using Orchestrator.Library.Services;
using MyProject.Models;
namespace MyProject.Workers;
public class MyWorker : EnhancedGenericWorker<MyJobData>
{
public MyWorker(
IZeebeClient zeebeClient,
ILogger<MyWorker> logger,
IOptions<BaseConfigKafka> configKafka,
IJobProcessor<MyJobData> jobProcessor,
IZeebeService zeebeService,
IKafkaMessageService? kafkaMessageService = null)
: base(zeebeClient, logger, "my-job-type", configKafka, jobProcessor, kafkaMessageService, zeebeService)
{
}
}
// MyWorkerHostedService.cs
using Microsoft.Extensions.Hosting;
using MyProject.Workers;
namespace MyProject.Services;
public class MyWorkerHostedService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<MyWorkerHostedService> _logger;
public MyWorkerHostedService(IServiceProvider serviceProvider, ILogger<MyWorkerHostedService> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Starting My Worker Hosted Service");
while (!stoppingToken.IsCancellationRequested)
{
try
{
using var scope = _serviceProvider.CreateScope();
var worker = scope.ServiceProvider.GetRequiredService<MyWorker>();
// Worker sẽ tự động xử lý jobs
await Task.Delay(1000, stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in worker hosted service");
await Task.Delay(5000, stoppingToken); // Wait before retry
}
}
}
}
{
"Zeebe": {
"GatewayAddress": "localhost:26500"
},
"Kafka": {
"BootstrapServers": "localhost:9092",
"GroupId": "my-worker-group"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Orchestrator.Library": "Debug",
"MyProject": "Debug"
}
}
}
// MyJobProcessorTests.cs
using Moq;
using Orchestrator.Library.Services;
using MyProject.Workers;
using MyProject.Models;
namespace MyProject.Tests;
[TestClass]
public class MyJobProcessorTests
{
[TestMethod]
public async Task ProcessJobAsync_ShouldCompleteJobSuccessfully()
{
// Arrange
var mockZeebeService = new Mock<IZeebeService>();
var mockLogger = new Mock<ILogger<MyJobProcessor>>();
var processor = new MyJobProcessor(mockZeebeService.Object, mockLogger.Object);
var jobClient = new Mock<IJobClient>();
var job = new Mock<IJob>();
job.Setup(j => j.Key).Returns(123);
var data = new MyJobData { Message = "test message", Priority = 1 };
// Act
await processor.ProcessJobAsync(jobClient.Object, job.Object, data, CancellationToken.None);
// Assert
mockZeebeService.Verify(x => x.CompleteJobAsync(
jobClient.Object,
job.Object.Key,
It.IsAny<object>()),
Times.Once);
}
}
dotnet build --configuration Release
dotnet publish --configuration Release --self-contained true --runtime win-x64
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyProject.csproj", "./"]
RUN dotnet restore "MyProject.csproj"
COPY . .
RUN dotnet build "MyProject.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyProject.dll"]
"Could not load file or assembly 'Orchestrator.Library'"
"No service for type 'IZeebeService' has been registered"
services.AddZeebeService()"Zeebe client connection failed"
// Enable detailed logging
services.AddLogging(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Debug);
});
// Log service registrations
services.AddZeebeService(provider => CreateZeebeClient(provider), options =>
{
options.EnableDetailedLogging = true;
});
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
Version 3.0.0 - Performance Optimized:
- NEW: Complete Task.Run wrapper for all consumer loops to prevent main thread blocking
- NEW: Dual-level Task.Run optimization (consumer loop + message processing)
- NEW: Enhanced error isolation and parallel message processing
- IMPROVED: Maximum throughput with non-blocking consumer architecture
- IMPROVED: Better resource utilization and scalability
- IMPROVED: Consumer stability and reliability
- FIXED: Potential consumer hanging issues in high-load scenarios
Version 2.0.0 - Enhanced Framework:
- NEW: BaseJobProcessor with template method pattern for common workflow
- NEW: HttpJobProcessor for specialized HTTP request handling
- NEW: KafkaJobProcessor for Kafka message publishing patterns
- NEW: JobContext wrapper with rich job information and utilities
- NEW: WorkerConfiguration and WorkerFactory for streamlined setup
- NEW: EnhancedGenericWorker with automatic retry and error handling
- IMPROVED: Configuration-driven approach for workers and processors
- IMPROVED: Enhanced error handling with ECode mapping
- BREAKING: Simplified processor interfaces - legacy support available
- Examples and comprehensive documentation included