{"id":16156580,"url":"https://github.com/oklahomer/protoactor-go-middleware-example","last_synced_at":"2025-04-07T01:19:56.309Z","repository":{"id":54515068,"uuid":"204240957","full_name":"oklahomer/protoactor-go-middleware-example","owner":"oklahomer","description":"Some example codes to illustrate how protoactor-go use Middleware","archived":false,"fork":false,"pushed_at":"2022-07-31T04:03:09.000Z","size":54,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-13T06:45:24.947Z","etag":null,"topics":["actor-model","golang","protoactor","protoactor-go"],"latest_commit_sha":null,"homepage":"https://blog.oklahome.net/2018/11/protoactor-go-middleware.html","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oklahomer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-25T03:26:32.000Z","updated_at":"2022-07-31T04:03:07.000Z","dependencies_parsed_at":"2022-08-13T18:20:41.667Z","dependency_job_id":null,"html_url":"https://github.com/oklahomer/protoactor-go-middleware-example","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oklahomer%2Fprotoactor-go-middleware-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oklahomer%2Fprotoactor-go-middleware-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oklahomer%2Fprotoactor-go-middleware-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oklahomer%2Fprotoactor-go-middleware-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oklahomer","download_url":"https://codeload.github.com/oklahomer/protoactor-go-middleware-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247574333,"owners_count":20960542,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actor-model","golang","protoactor","protoactor-go"],"created_at":"2024-10-10T01:45:21.028Z","updated_at":"2025-04-07T01:19:56.283Z","avatar_url":"https://github.com/oklahomer.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Goal\nThis repository demonstrates how `InboundMiddleware` and `OutboundMiddleware` work in [protoacgor-go](https://github.com/asynkron/protoactor-go)'s actor model.\n\n# InboundMiddleware and OutboundMiddleware\nSee `example/main.go` for the regular middleware usage.\nThis shows how middleware can be defined and how nested middleware chain is called.\n\nThe execution of `go run example/main.go` will output log messages somewhat like the below:\n```\n» go run example/main.go\n2022/07/31 12:54:55 ReceiverMiddleware: start handling incoming message #1: \u0026actor.Started{}\n2022/07/31 12:54:55 Nested ReceiverMiddleware: start handling incoming message: \u0026actor.Started{}\n2022/07/31 12:54:55 Actor: received \u0026actor.Started{}\n2022/07/31 12:54:55 Nested ReceiverMiddleware: end handling incoming message: \u0026actor.Started{}\n2022/07/31 12:54:55 ReceiverMiddleware: end handling incoming message #1: \u0026actor.Started{}\n2022/07/31 12:54:56 ReceiverMiddleware: start handling incoming message #2: struct {}{}\n2022/07/31 12:54:56 Nested ReceiverMiddleware: start handling incoming message: struct {}{}\n2022/07/31 12:54:56 Actor: received signal\n2022/07/31 12:54:56 SenderMiddleware: start sending message #1 to pong\n2022/07/31 12:54:56 SenderMiddleware: end sending message #1 to pong\n2022/07/31 12:54:56 Nested ReceiverMiddleware: end handling incoming message: struct {}{}\n2022/07/31 12:54:56 ReceiverMiddleware: end handling incoming message #2: struct {}{}\n2022/07/31 12:54:56 ReceiverMiddleware: start handling incoming message #3: \u0026main.pong{}\n2022/07/31 12:54:56 Nested ReceiverMiddleware: start handling incoming message: \u0026main.pong{}\n2022/07/31 12:54:56 Actor: received pong\n2022/07/31 12:54:56 Nested ReceiverMiddleware: end handling incoming message: \u0026main.pong{}\n2022/07/31 12:54:56 ReceiverMiddleware: end handling incoming message #3: \u0026main.pong{}\n2022/07/31 12:54:57 ReceiverMiddleware: start handling incoming message #4: struct {}{}\n2022/07/31 12:54:57 Nested ReceiverMiddleware: start handling incoming message: struct {}{}\n2022/07/31 12:54:57 Actor: received signal\n2022/07/31 12:54:57 SenderMiddleware: start sending message #2 to pong\n2022/07/31 12:54:57 SenderMiddleware: end sending message #2 to pong\n2022/07/31 12:54:57 Nested ReceiverMiddleware: end handling incoming message: struct {}{}\n2022/07/31 12:54:57 ReceiverMiddleware: end handling incoming message #4: struct {}{}\n2022/07/31 12:54:57 ReceiverMiddleware: start handling incoming message #5: \u0026main.pong{}\n2022/07/31 12:54:57 Nested ReceiverMiddleware: start handling incoming message: \u0026main.pong{}\n2022/07/31 12:54:57 Actor: received pong\n2022/07/31 12:54:57 Nested ReceiverMiddleware: end handling incoming message: \u0026main.pong{}\n2022/07/31 12:54:57 ReceiverMiddleware: end handling incoming message #5: \u0026main.pong{}\n2022/07/31 12:54:58 ReceiverMiddleware: start handling incoming message #6: struct {}{}\n2022/07/31 12:54:58 Nested ReceiverMiddleware: start handling incoming message: struct {}{}\n2022/07/31 12:54:58 Actor: received signal\n2022/07/31 12:54:58 SenderMiddleware: start sending message #3 to pong\n2022/07/31 12:54:58 SenderMiddleware: end sending message #3 to pong\n2022/07/31 12:54:58 Nested ReceiverMiddleware: end handling incoming message: struct {}{}\n2022/07/31 12:54:58 ReceiverMiddleware: end handling incoming message #6: struct {}{}\n2022/07/31 12:54:58 ReceiverMiddleware: start handling incoming message #7: \u0026main.pong{}\n2022/07/31 12:54:58 Nested ReceiverMiddleware: start handling incoming message: \u0026main.pong{}\n2022/07/31 12:54:58 Actor: received pong\n2022/07/31 12:54:58 Nested ReceiverMiddleware: end handling incoming message: \u0026main.pong{}\n2022/07/31 12:54:58 ReceiverMiddleware: end handling incoming message #7: \u0026main.pong{}\n2022/07/31 12:54:58 ReceiverMiddleware: start handling incoming message #8: \u0026actor.Stopping{}\n2022/07/31 12:54:58 Nested ReceiverMiddleware: start handling incoming message: \u0026actor.Stopping{}\n2022/07/31 12:54:58 Actor: received \u0026actor.Stopping{}\n2022/07/31 12:54:58 Nested ReceiverMiddleware: end handling incoming message: \u0026actor.Stopping{}\n2022/07/31 12:54:58 ReceiverMiddleware: end handling incoming message #8: \u0026actor.Stopping{}\n2022/07/31 12:54:58 ReceiverMiddleware: start handling incoming message #9: \u0026actor.Stopped{}\n2022/07/31 12:54:58 Nested ReceiverMiddleware: start handling incoming message: \u0026actor.Stopped{}\n2022/07/31 12:54:58 Actor: received \u0026actor.Stopped{}\n2022/07/31 12:54:58 Nested ReceiverMiddleware: end handling incoming message: \u0026actor.Stopped{}\n2022/07/31 12:54:58 ReceiverMiddleware: end handling incoming message #9: \u0026actor.Stopped{}\n2022/07/31 12:54:58 Finish\n```\n\n# Plugin\nWhile `example/main.go` shows how a regular middleware works, `plugin/main.go` describes how a middleware construction with [`plugin`](https://github.com/asynkron/protoactor-go/blob/afd2d973a1d1/plugin/plugin.go) mechanism runs.\nThis kind of middleware construction is especially used in `protoactor-go` to build setup a [`PassivationPlugin`](https://github.com/asynkron/protoactor-go/blob/afd2d973a1d1/plugin/passivation.go).\n`PassivationPlugin` is a designated middleware that runs a initialization code on actor start and runs another logic on other message receptions.\nThis is mainly used to let a cluster grain start a timer on actor initialization, reset the timer on every message reception and stop the actor when no message comes before the timer ticks.\nRemember that, in protoactor's cluster grain architecture, Cluster Grains always \"exist.\"\nWhen no Cluster Grain actor exists on message reception, an actor is created; when no message follows during a pre-defined interval, the actor stops to save server resources.\n\nExecution of `go run plugin/main.go` will output log messages somewhat like below:\n```\n» go run plugin/main.go\n2022/07/31 12:44:39 Middleware: starting $1\n2022/07/31 12:44:39 Actor: received \u0026actor.Started{}\n2022/07/31 12:44:39 Middleware: received \u0026actor.Stopping{}\n2022/07/31 12:44:39 Actor: received \u0026actor.Stopping{}\n2022/07/31 12:44:39 Middleware: received \u0026actor.Stopped{}\n2022/07/31 12:44:39 Actor: received \u0026actor.Stopped{}\n```\n\n# References\n- [[Golang] Protoactor-go 101: Introduction to golang's actor model implementation](https://blog.oklahome.net/2018/07/protoactor-go-introduction.html)\n- [[Golang] Protoactor-go 101: How actors communicate with each other](https://blog.oklahome.net/2018/09/protoactor-go-messaging-protocol.html)\n- [[Golang] protoactor-go 101: How actor.Future works to synchronize concurrent task execution](https://blog.oklahome.net/2018/11/protoactor-go-how-future-works.html)\n- [[Golang] protoactor-go 201: How middleware works to intercept incoming and outgoing messages](https://blog.oklahome.net/2018/11/protoactor-go-middleware.html)\n- [[Golang] protoactor-go 201: Use plugins to add behaviors to an actor](https://blog.oklahome.net/2018/12/protoactor-go-use-plugin-to-add-behavior.html)\n- [[Golang] protoactor-go 301: How proto.actor's clustering works to achieve higher availability](https://blog.oklahome.net/2021/05/protoactor-clustering.html)\n\n# Other Example Codes\n- [oklahomer/protoactor-go-sender-example](https://github.com/oklahomer/protoactor-go-sender-example)\n  - Some example codes to illustrate how protoactor-go refers to sender process\n- [oklahomer/protoactor-go-future-example](https://github.com/oklahomer/protoactor-go-future-example)\n  - Some example codes to illustrate how protoactor-go handles Future process\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foklahomer%2Fprotoactor-go-middleware-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foklahomer%2Fprotoactor-go-middleware-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foklahomer%2Fprotoactor-go-middleware-example/lists"}