github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/protobuf/protoc-gen-go-grain/test/multi-services/services_grain.pb.go (about)

     1  // Code generated by protoc-gen-grain. DO NOT EDIT.
     2  // versions:
     3  //  protoc-gen-grain v0.6.0
     4  //  protoc           v4.25.0
     5  // source: test/multi-services/services.proto
     6  
     7  package hello
     8  
     9  import (
    10  	fmt "fmt"
    11  	actor "github.com/asynkron/protoactor-go/actor"
    12  	cluster "github.com/asynkron/protoactor-go/cluster"
    13  	proto "google.golang.org/protobuf/proto"
    14  	emptypb "google.golang.org/protobuf/types/known/emptypb"
    15  	slog "log/slog"
    16  	time "time"
    17  )
    18  
    19  var xHelloFactory func() Hello
    20  
    21  // HelloFactory produces a Hello
    22  func HelloFactory(factory func() Hello) {
    23  	xHelloFactory = factory
    24  }
    25  
    26  // GetHelloGrainClient instantiates a new HelloGrainClient with given Identity
    27  func GetHelloGrainClient(c *cluster.Cluster, id string) *HelloGrainClient {
    28  	if c == nil {
    29  		panic(fmt.Errorf("nil cluster instance"))
    30  	}
    31  	if id == "" {
    32  		panic(fmt.Errorf("empty id"))
    33  	}
    34  	return &HelloGrainClient{Identity: id, cluster: c}
    35  }
    36  
    37  // GetHelloKind instantiates a new cluster.Kind for Hello
    38  func GetHelloKind(opts ...actor.PropsOption) *cluster.Kind {
    39  	props := actor.PropsFromProducer(func() actor.Actor {
    40  		return &HelloActor{
    41  			Timeout: 60 * time.Second,
    42  		}
    43  	}, opts...)
    44  	kind := cluster.NewKind("Hello", props)
    45  	return kind
    46  }
    47  
    48  // GetHelloKind instantiates a new cluster.Kind for Hello
    49  func NewHelloKind(factory func() Hello, timeout time.Duration, opts ...actor.PropsOption) *cluster.Kind {
    50  	xHelloFactory = factory
    51  	props := actor.PropsFromProducer(func() actor.Actor {
    52  		return &HelloActor{
    53  			Timeout: timeout,
    54  		}
    55  	}, opts...)
    56  	kind := cluster.NewKind("Hello", props)
    57  	return kind
    58  }
    59  
    60  // Hello interfaces the services available to the Hello
    61  type Hello interface {
    62  	Init(ctx cluster.GrainContext)
    63  	Terminate(ctx cluster.GrainContext)
    64  	ReceiveDefault(ctx cluster.GrainContext)
    65  	SayHello(req *emptypb.Empty, ctx cluster.GrainContext) (*SayHelloResponse, error)
    66  }
    67  
    68  // HelloGrainClient holds the base data for the HelloGrain
    69  type HelloGrainClient struct {
    70  	Identity string
    71  	cluster  *cluster.Cluster
    72  }
    73  
    74  // SayHello requests the execution on to the cluster with CallOptions
    75  func (g *HelloGrainClient) SayHello(r *emptypb.Empty, opts ...cluster.GrainCallOption) (*SayHelloResponse, error) {
    76  	bytes, err := proto.Marshal(r)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	reqMsg := &cluster.GrainRequest{MethodIndex: 0, MessageData: bytes}
    81  	resp, err := g.cluster.Request(g.Identity, "Hello", reqMsg, opts...)
    82  	if err != nil {
    83  		return nil, fmt.Errorf("error request: %w", err)
    84  	}
    85  	switch msg := resp.(type) {
    86  	case *SayHelloResponse:
    87  		return msg, nil
    88  	case *cluster.GrainErrorResponse:
    89  		if msg == nil {
    90  			return nil, nil
    91  		}
    92  		return nil, msg
    93  	default:
    94  		return nil, fmt.Errorf("unknown response type %T", resp)
    95  	}
    96  }
    97  
    98  // HelloActor represents the actor structure
    99  type HelloActor struct {
   100  	ctx     cluster.GrainContext
   101  	inner   Hello
   102  	Timeout time.Duration
   103  }
   104  
   105  // Receive ensures the lifecycle of the actor for the received message
   106  func (a *HelloActor) Receive(ctx actor.Context) {
   107  	switch msg := ctx.Message().(type) {
   108  	case *actor.Started: //pass
   109  	case *cluster.ClusterInit:
   110  		a.ctx = cluster.NewGrainContext(ctx, msg.Identity, msg.Cluster)
   111  		a.inner = xHelloFactory()
   112  		a.inner.Init(a.ctx)
   113  
   114  		if a.Timeout > 0 {
   115  			ctx.SetReceiveTimeout(a.Timeout)
   116  		}
   117  	case *actor.ReceiveTimeout:
   118  		ctx.Poison(ctx.Self())
   119  	case *actor.Stopped:
   120  		a.inner.Terminate(a.ctx)
   121  	case actor.AutoReceiveMessage: // pass
   122  	case actor.SystemMessage: // pass
   123  
   124  	case *cluster.GrainRequest:
   125  		switch msg.MethodIndex {
   126  		case 0:
   127  			req := &emptypb.Empty{}
   128  			err := proto.Unmarshal(msg.MessageData, req)
   129  			if err != nil {
   130  				ctx.Logger().Error("[Grain] SayHello(emptypb.Empty) proto.Unmarshal failed.", slog.Any("error", err))
   131  				resp := cluster.NewGrainErrorResponse(cluster.ErrorReason_INVALID_ARGUMENT, err.Error()).
   132  					WithMetadata(map[string]string{
   133  						"argument": req.String(),
   134  					})
   135  				ctx.Respond(resp)
   136  				return
   137  			}
   138  
   139  			r0, err := a.inner.SayHello(req, a.ctx)
   140  			if err != nil {
   141  				resp := cluster.FromError(err)
   142  				ctx.Respond(resp)
   143  				return
   144  			}
   145  			ctx.Respond(r0)
   146  		}
   147  	default:
   148  		a.inner.ReceiveDefault(a.ctx)
   149  	}
   150  }
   151  
   152  // onError should be used in ctx.ReenterAfter
   153  // you can just return error in reenterable method for other errors
   154  func (a *HelloActor) onError(err error) {
   155  	resp := cluster.FromError(err)
   156  	a.ctx.Respond(resp)
   157  }
   158  
   159  var xWorkFactory func() Work
   160  
   161  // WorkFactory produces a Work
   162  func WorkFactory(factory func() Work) {
   163  	xWorkFactory = factory
   164  }
   165  
   166  // GetWorkGrainClient instantiates a new WorkGrainClient with given Identity
   167  func GetWorkGrainClient(c *cluster.Cluster, id string) *WorkGrainClient {
   168  	if c == nil {
   169  		panic(fmt.Errorf("nil cluster instance"))
   170  	}
   171  	if id == "" {
   172  		panic(fmt.Errorf("empty id"))
   173  	}
   174  	return &WorkGrainClient{Identity: id, cluster: c}
   175  }
   176  
   177  // GetWorkKind instantiates a new cluster.Kind for Work
   178  func GetWorkKind(opts ...actor.PropsOption) *cluster.Kind {
   179  	props := actor.PropsFromProducer(func() actor.Actor {
   180  		return &WorkActor{
   181  			Timeout: 60 * time.Second,
   182  		}
   183  	}, opts...)
   184  	kind := cluster.NewKind("Work", props)
   185  	return kind
   186  }
   187  
   188  // GetWorkKind instantiates a new cluster.Kind for Work
   189  func NewWorkKind(factory func() Work, timeout time.Duration, opts ...actor.PropsOption) *cluster.Kind {
   190  	xWorkFactory = factory
   191  	props := actor.PropsFromProducer(func() actor.Actor {
   192  		return &WorkActor{
   193  			Timeout: timeout,
   194  		}
   195  	}, opts...)
   196  	kind := cluster.NewKind("Work", props)
   197  	return kind
   198  }
   199  
   200  // Work interfaces the services available to the Work
   201  type Work interface {
   202  	Init(ctx cluster.GrainContext)
   203  	Terminate(ctx cluster.GrainContext)
   204  	ReceiveDefault(ctx cluster.GrainContext)
   205  	DoWork(req *DoWorkRequest, ctx cluster.GrainContext) (*DoWorkResponse, error)
   206  }
   207  
   208  // WorkGrainClient holds the base data for the WorkGrain
   209  type WorkGrainClient struct {
   210  	Identity string
   211  	cluster  *cluster.Cluster
   212  }
   213  
   214  // DoWork requests the execution on to the cluster with CallOptions
   215  func (g *WorkGrainClient) DoWork(r *DoWorkRequest, opts ...cluster.GrainCallOption) (*DoWorkResponse, error) {
   216  	bytes, err := proto.Marshal(r)
   217  	if err != nil {
   218  		return nil, err
   219  	}
   220  	reqMsg := &cluster.GrainRequest{MethodIndex: 0, MessageData: bytes}
   221  	resp, err := g.cluster.Request(g.Identity, "Work", reqMsg, opts...)
   222  	if err != nil {
   223  		return nil, fmt.Errorf("error request: %w", err)
   224  	}
   225  	switch msg := resp.(type) {
   226  	case *DoWorkResponse:
   227  		return msg, nil
   228  	case *cluster.GrainErrorResponse:
   229  		if msg == nil {
   230  			return nil, nil
   231  		}
   232  		return nil, msg
   233  	default:
   234  		return nil, fmt.Errorf("unknown response type %T", resp)
   235  	}
   236  }
   237  
   238  // WorkActor represents the actor structure
   239  type WorkActor struct {
   240  	ctx     cluster.GrainContext
   241  	inner   Work
   242  	Timeout time.Duration
   243  }
   244  
   245  // Receive ensures the lifecycle of the actor for the received message
   246  func (a *WorkActor) Receive(ctx actor.Context) {
   247  	switch msg := ctx.Message().(type) {
   248  	case *actor.Started: //pass
   249  	case *cluster.ClusterInit:
   250  		a.ctx = cluster.NewGrainContext(ctx, msg.Identity, msg.Cluster)
   251  		a.inner = xWorkFactory()
   252  		a.inner.Init(a.ctx)
   253  
   254  		if a.Timeout > 0 {
   255  			ctx.SetReceiveTimeout(a.Timeout)
   256  		}
   257  	case *actor.ReceiveTimeout:
   258  		ctx.Poison(ctx.Self())
   259  	case *actor.Stopped:
   260  		a.inner.Terminate(a.ctx)
   261  	case actor.AutoReceiveMessage: // pass
   262  	case actor.SystemMessage: // pass
   263  
   264  	case *cluster.GrainRequest:
   265  		switch msg.MethodIndex {
   266  		case 0:
   267  			req := &DoWorkRequest{}
   268  			err := proto.Unmarshal(msg.MessageData, req)
   269  			if err != nil {
   270  				ctx.Logger().Error("[Grain] DoWork(DoWorkRequest) proto.Unmarshal failed.", slog.Any("error", err))
   271  				resp := cluster.NewGrainErrorResponse(cluster.ErrorReason_INVALID_ARGUMENT, err.Error()).
   272  					WithMetadata(map[string]string{
   273  						"argument": req.String(),
   274  					})
   275  				ctx.Respond(resp)
   276  				return
   277  			}
   278  
   279  			r0, err := a.inner.DoWork(req, a.ctx)
   280  			if err != nil {
   281  				resp := cluster.FromError(err)
   282  				ctx.Respond(resp)
   283  				return
   284  			}
   285  			ctx.Respond(r0)
   286  		}
   287  	default:
   288  		a.inner.ReceiveDefault(a.ctx)
   289  	}
   290  }
   291  
   292  // onError should be used in ctx.ReenterAfter
   293  // you can just return error in reenterable method for other errors
   294  func (a *WorkActor) onError(err error) {
   295  	resp := cluster.FromError(err)
   296  	a.ctx.Respond(resp)
   297  }
   298  
   299  func respond[T proto.Message](ctx cluster.GrainContext) func(T) {
   300  	return func(resp T) {
   301  		ctx.Respond(resp)
   302  	}
   303  }