Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,7 @@ Metrics/ParameterLists:
# We want our require lists to be in order
Style/RequireOrder:
Enabled: true

# Feature files may have many classes in the file
Style/OneClassPerFile:
Enabled: false
5 changes: 3 additions & 2 deletions features/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ toolchain go1.24.3

require (
github.com/google/uuid v1.6.0
github.com/nexus-rpc/sdk-go v0.5.1
github.com/stretchr/testify v1.10.0
github.com/temporalio/features/harness/go v0.0.0-00010101000000-000000000000
github.com/uber-go/tally/v4 v4.1.1
github.com/urfave/cli/v2 v2.3.0
go.temporal.io/api v1.60.0
go.temporal.io/sdk v1.37.0
go.temporal.io/api v1.62.1
go.temporal.io/sdk v1.40.0
go.temporal.io/sdk/contrib/tally v0.2.0
golang.org/x/mod v0.17.0
google.golang.org/grpc v1.67.1
Expand Down
12 changes: 6 additions & 6 deletions features/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nexus-rpc/sdk-go v0.3.0 h1:Y3B0kLYbMhd4C2u00kcYajvmOrfozEtTV/nHSnV57jA=
github.com/nexus-rpc/sdk-go v0.3.0/go.mod h1:TpfkM2Cw0Rlk9drGkoiSMpFqflKTiQLWUNyKJjF8mKQ=
github.com/nexus-rpc/sdk-go v0.5.1 h1:UFYYfoHlQc+Pn9gQpmn9QE7xluewAn2AO1OSkAh7YFU=
github.com/nexus-rpc/sdk-go v0.5.1/go.mod h1:FHdPfVQwRuJFZFTF0Y2GOAxCrbIBNrcPna9slkGKPYk=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
Expand Down Expand Up @@ -182,11 +182,11 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.temporal.io/api v1.5.0/go.mod h1:BqKxEJJYdxb5dqf0ODfzfMxh8UEQ5L3zKS51FiIYYkA=
go.temporal.io/api v1.60.0 h1:SlRkizt3PXu/J62NWlUNLldHtJhUxfsBRuF4T0KYkgY=
go.temporal.io/api v1.60.0/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM=
go.temporal.io/api v1.62.1 h1:7UHMNOIqfYBVTaW0JIh/wDpw2jORkB6zUKsxGtvjSZU=
go.temporal.io/api v1.62.1/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM=
go.temporal.io/sdk v1.12.0/go.mod h1:lSp3lH1lI0TyOsus0arnO3FYvjVXBZGi/G7DjnAnm6o=
go.temporal.io/sdk v1.37.0 h1:RbwCkUQuqY4rfCzdrDZF9lgT7QWG/pHlxfZFq0NPpDQ=
go.temporal.io/sdk v1.37.0/go.mod h1:tOy6vGonfAjrpCl6Bbw/8slTgQMiqvoyegRv2ZHPm5M=
go.temporal.io/sdk v1.40.0 h1:n9JN3ezVpWBxLzz5xViCo0sKxp7kVVhr1Su0bcMRNNs=
go.temporal.io/sdk v1.40.0/go.mod h1:tauxVfN174F0bdEs27+i0h8UPD7xBb6Py2SPHo7f1C0=
go.temporal.io/sdk/contrib/tally v0.2.0 h1:XnTJIQcjOv+WuCJ1u8Ve2nq+s2H4i/fys34MnWDRrOo=
go.temporal.io/sdk/contrib/tally v0.2.0/go.mod h1:1kpSuCms/tHeJQDPuuKkaBsMqfHnIIRnCtUYlPNXxuE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
Expand Down
107 changes: 107 additions & 0 deletions features/snippets/plugins/plugins.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using NexusRpc;
using NexusRpc.Handlers;
using Temporalio.Activities;
using Temporalio.Api.Common.V1;
using Temporalio.Client.Interceptors;
using Temporalio.Common;
using Temporalio.Converters;
using Temporalio.Nexus;
using Temporalio.Worker.Interceptors;
using Temporalio.Workflows;

class PluginsSnippet
{
// @@@SNIPSTART dotnet-plugins-activity
[Activity]
static void SomeActivity() => throw new NotImplementedException();

SimplePlugin activityPlugin = new SimplePlugin(
"PluginName",
new SimplePluginOptions() { }.AddActivity(SomeActivity));
// @@@SNIPEND

// @@@SNIPSTART dotnet-plugins-workflow
[Workflow]
class SimpleWorkflow
{
[WorkflowRun]
public Task<string> RunAsync(string name) => Task.FromResult($"Hello, {name}!");
}

SimplePlugin workflowPlugin = new SimplePlugin(
"PluginName",
new SimplePluginOptions() { }.AddWorkflow<SimpleWorkflow>());
// @@@SNIPEND

// @@@SNIPSTART dotnet-plugins-nexus
[NexusService]
public interface IStringService
{
[NexusOperation]
string DoSomething(string name);
}

[NexusServiceHandler(typeof(IStringService))]
public class HandlerFactoryStringService
{
private readonly Func<IOperationHandler<string, string>> handlerFactory;

public HandlerFactoryStringService(Func<IOperationHandler<string, string>> handlerFactory) =>
this.handlerFactory = handlerFactory;

[NexusOperationHandler]
public IOperationHandler<string, string> DoSomething() => handlerFactory();
}

SimplePlugin nexusPlugin = new SimplePlugin(
"PluginName",
new SimplePluginOptions() { }.AddNexusService(new HandlerFactoryStringService(() =>
OperationHandler.Sync<string, string>((ctx, name) => $"Hello, {name}")))
);
// @@@SNIPEND

// @@@SNIPSTART dotnet-plugins-converter
private class Codec : IPayloadCodec
{
public Task<IReadOnlyCollection<Payload>> EncodeAsync(IReadOnlyCollection<Payload> payloads) => throw new NotImplementedException();
public Task<IReadOnlyCollection<Payload>> DecodeAsync(IReadOnlyCollection<Payload> payloads) => throw new NotImplementedException();
}

SimplePlugin converterPlugin = new SimplePlugin(
"PluginName",
new SimplePluginOptions()
{
DataConverterOption = new SimplePluginOptions.SimplePluginOption<DataConverter>(
(converter) => converter with { PayloadCodec = new Codec() }
),
});
// @@@SNIPEND

// @@@SNIPSTART dotnet-plugins-interceptors
private class SomeClientInterceptor : IClientInterceptor
{
public ClientOutboundInterceptor InterceptClient(
ClientOutboundInterceptor nextInterceptor) =>
throw new NotImplementedException();
}

private class SomeWorkerInterceptor : IWorkerInterceptor
{
public WorkflowInboundInterceptor InterceptWorkflow(
WorkflowInboundInterceptor nextInterceptor) =>
throw new NotImplementedException();

public ActivityInboundInterceptor InterceptActivity(
ActivityInboundInterceptor nextInterceptor) =>
throw new NotImplementedException();
}

SimplePlugin interceptorPlugin = new SimplePlugin(
"PluginName",
new SimplePluginOptions()
{
ClientInterceptors = new List<IClientInterceptor>() { new SomeClientInterceptor() },
WorkerInterceptors = new List<IWorkerInterceptor>() { new SomeWorkerInterceptor() },
});
// @@@SNIPEND
}
120 changes: 120 additions & 0 deletions features/snippets/plugins/plugins.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package plugins

import (
"context"

"github.com/nexus-rpc/sdk-go/nexus"
"go.temporal.io/sdk/activity"
"go.temporal.io/sdk/converter"
"go.temporal.io/sdk/interceptor"
"go.temporal.io/sdk/temporal"
"go.temporal.io/sdk/workflow"
)

// @@@SNIPSTART go-plugin-activity
func SomeActivity(ctx context.Context) error {
// Activity implementation
return nil
}

func createActivityPlugin() (*temporal.SimplePlugin, error) {
return temporal.NewSimplePlugin(temporal.SimplePluginOptions{
Name: "PluginName",
RunContextBefore: func(ctx context.Context, options temporal.SimplePluginRunContextBeforeOptions) error {
options.Registry.RegisterActivityWithOptions(
SomeActivity,
activity.RegisterOptions{Name: "SomeActivity"},
)
return nil
},
})
}

// @@@SNIPEND

// @@@SNIPSTART go-plugin-workflow
func HelloWorkflow(ctx workflow.Context, name string) (string, error) {
return "Hello, " + name + "!", nil
}

func createWorkflowPlugin() (*temporal.SimplePlugin, error) {
return temporal.NewSimplePlugin(temporal.SimplePluginOptions{
Name: "PluginName",
RunContextBefore: func(ctx context.Context, options temporal.SimplePluginRunContextBeforeOptions) error {
options.Registry.RegisterWorkflowWithOptions(
HelloWorkflow,
workflow.RegisterOptions{Name: "HelloWorkflow"},
)
return nil
},
})
}

// @@@SNIPEND

// @@@SNIPSTART go-plugin-nexus
type WeatherInput struct {
City string `json:"city"`
}

type Weather struct {
City string `json:"city"`
TemperatureRange string `json:"temperatureRange"`
Conditions string `json:"conditions"`
}

var WeatherService = nexus.NewService("weather-service")

var GetWeatherOperation = nexus.NewSyncOperation(
"get-weather",
func(ctx context.Context, input WeatherInput, options nexus.StartOperationOptions) (Weather, error) {
return Weather{
City: input.City,
TemperatureRange: "14-20C",
Conditions: "Sunny with wind.",
}, nil
},
)

func createNexusPlugin() (*temporal.SimplePlugin, error) {
return temporal.NewSimplePlugin(temporal.SimplePluginOptions{
Name: "PluginName",
RunContextBefore: func(ctx context.Context, options temporal.SimplePluginRunContextBeforeOptions) error {
options.Registry.RegisterNexusService(WeatherService)
return nil
},
})
}

// @@@SNIPEND

// @@@SNIPSTART go-plugin-converter
func createConverterPlugin() (*temporal.SimplePlugin, error) {
customConverter := converter.GetDefaultDataConverter() // Or your custom converter

return temporal.NewSimplePlugin(temporal.SimplePluginOptions{
Name: "PluginName",
DataConverter: customConverter,
})
}

// @@@SNIPEND

// @@@SNIPSTART go-plugin-interceptors
type SomeWorkerInterceptor struct {
interceptor.WorkerInterceptorBase
}

type SomeClientInterceptor struct {
interceptor.ClientInterceptorBase
}

func createInterceptorPlugin() (*temporal.SimplePlugin, error) {
return temporal.NewSimplePlugin(temporal.SimplePluginOptions{
Name: "PluginName",
WorkerInterceptors: []interceptor.WorkerInterceptor{&SomeWorkerInterceptor{}},
ClientInterceptors: []interceptor.ClientInterceptor{&SomeClientInterceptor{}},
})
}

// @@@SNIPEND
Loading
Loading