Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial dotnet Reaction SDK #112

Merged
merged 20 commits into from
Nov 14, 2024

Conversation

danielgerlag
Copy link
Contributor

Reaction SDK for Drasi

This library provides the building blocks and infrastructure to implement a Drasi Reaction in .NET

Getting started

Install the package

dotnet add package Drasi.Reaction.SDK

Basic example

The following example simply breaks down and logs the various parts of the incoming change event from a Continuous Query.

var builder = new ReactionBuilder();

builder.UseChangeEventHandler(async (evt, queryConfig) =>
{
    Console.WriteLine($"Received change event from query {evt.QueryId} sequence {evt.Sequence}");
    
    foreach (var item in evt.AddedResults)
        Console.WriteLine($"Added result: {item}");

    foreach (var item in evt.UpdatedResults)
        Console.WriteLine($"Updated result, before {item.Before}, after {item.After}");

    foreach (var item in evt.DeletedResults)
        Console.WriteLine($"Deleted result: {item}");

});

var reaction = builder.Build();
await reaction.StartAsync();

A more advanced example

The following example illustrates

  • Retrieving a configuration value from the Reaction manifest
  • Defining a custom per query configuration object
  • Parsing the per query configuration object from Yaml
  • Process change events form thw query
  • Process control events (start, stop, etc.) from the query
var reaction = new ReactionBuilder<MyQueryConfig>()
    .UseChangeEventHandler<MyChangeHandler>()               // Use your custom change handler
    .UseControlEventHandler<MyControlSignalHandler>()       // Use your custom control signal handler
    .UseYamlQueryConfig()                                   // Parse the per query configuration from Yaml
    .ConfigureServices((services) =>                        // Register your own services
    {
        services.AddSingleton<MyService>();
    })
    .Build();

// Start the reaction
await reaction.StartAsync();

// Define a custom per query configuration object
class MyQueryConfig
{
    [JsonPropertyName("greeting")]
    public string? Greeting { get; set; }
}

// Your own internal service
class MyService
{
    private readonly string _connectionString;

    public MyService(IConfiguration configuration)
    {
        // Retrieve the connection string from the Reaction configuration
        _connectionString = configuration["MyConnectionString"];
    }

    public void DoSomething()
    {
        Console.WriteLine("Doing something");
    }
}

// Define a custom change handler, that uses your service
class MyChangeHandler : IChangeEventHandler<MyQueryConfig>
{   
    private readonly MyService _service;
    private readonly ILogger<MyChangeHandler> _logger;

    public MyChangeHandler(MyService service, ILogger<MyChangeHandler> logger)
    {
        _service = service;
        _logger = logger;
    }

    public async Task HandleChange(ChangeEvent evt, MyQueryConfig? queryConfig)
    {
        _logger.LogInformation($"Received change event from query {evt.QueryId} sequence {evt.Sequence}. Query greeting is {queryConfig?.Greeting}");
        _logger.LogInformation($"Full event: {evt.ToJson()}");
        _service.DoSomething();
    }
}

// Define a custom control signal handler
class MyControlSignalHandler : IControlEventHandler<MyQueryConfig>
{
    private readonly ILogger<MyControlSignalHandler> _logger;

    public MyControlSignalHandler(ILogger<MyControlSignalHandler> logger)
    {
        _logger = logger;
    }

    public async Task HandleControlSignal(ControlEvent evt, MyQueryConfig? queryConfig)
    {
        _logger.LogWarning($"Received control signal: {evt.ControlSignal?.Kind} for query {evt.QueryId}. Query greeting is {queryConfig?.Greeting}");
    }
}

@danielgerlag danielgerlag requested a review from a team as a code owner November 8, 2024 23:40
_logger = logger;
}

public async Task HandleChange(ChangeEvent evt, MyQueryConfig? queryConfig)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have to specify a queryconfig object in order to define the HandleChange method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the default is System.Object if you do not specify one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

- Retrieving a configuration value from the Reaction manifest
- Defining a custom per query configuration object
- Parsing the per query configuration object from Yaml
- Process change events form thw query
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo

@danielgerlag danielgerlag merged commit 44a2329 into drasi-project:main Nov 14, 2024
30 checks passed
ruokun-niu added a commit to ruokun-niu/drasi-platform that referenced this pull request Nov 19, 2024
…iu/drasi-platform into review-gremlin-reaction

* 'review-gremlin-reaction' of https://github.com/ruokun-niu/drasi-platform:
  Initial dotnet Reaction SDK (drasi-project#112)
  Update steps to build locally in contributing docs (drasi-project#108)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants