{"id":18438272,"url":"https://github.com/pumpkinseed/npc","last_synced_at":"2025-04-14T13:16:02.158Z","repository":{"id":57603222,"uuid":"118044964","full_name":"PumpkinSeed/npc","owner":"PumpkinSeed","description":"RPC framework for NSQ","archived":false,"fork":false,"pushed_at":"2019-05-13T20:59:33.000Z","size":162,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-14T13:15:53.134Z","etag":null,"topics":["nsq","rpc","rpc-framework"],"latest_commit_sha":null,"homepage":"","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/PumpkinSeed.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":"2018-01-18T22:18:13.000Z","updated_at":"2022-02-24T01:08:52.000Z","dependencies_parsed_at":"2022-09-26T20:01:42.248Z","dependency_job_id":null,"html_url":"https://github.com/PumpkinSeed/npc","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PumpkinSeed%2Fnpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PumpkinSeed%2Fnpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PumpkinSeed%2Fnpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PumpkinSeed%2Fnpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PumpkinSeed","download_url":"https://codeload.github.com/PumpkinSeed/npc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248886343,"owners_count":21177645,"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":["nsq","rpc","rpc-framework"],"created_at":"2024-11-06T06:19:18.605Z","updated_at":"2025-04-14T13:16:02.104Z","avatar_url":"https://github.com/PumpkinSeed.png","language":"Go","readme":"# npc\nRPC framework for NSQ\n\n[![Documentation](https://godoc.org/github.com/PumpkinSeed/npc?status.svg)](https://godoc.org/github.com/PumpkinSeed/npc) \n\n- [Usage](#usage)\n\t- [Server](#server)\n\t- [Client](#client)\n\t- [Details](#details) (Logger, Configs, AppServer, Interrupter)\n\n## Usage\n\n```\ngo get github.com/PumpkinSeed/npc\n```\n\n### Server\n\nServer implements an exact rpc server which is listening on the request topic and consume the message than publish the answer to the response topic determined in the Envelope (Envelope not seen by the user of the library, it's just for the inner communication).\n\nCreate a server using the `npc.New({TYPE})`, `Init({PRODUCER_CONFIG}, {CONSUMER_CONFIG}, {REQUEST_TOPIC}, {NSQ_CHANNEL}, {LOGGER})` and the `Server({rpc.AppServer})`. The type in this case will be `npc.Server`. After start the listener with the `Listen()` method. More information about the [details](#details) section.\n\n```\npackage main\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/PumpkinSeed/npc\"\n\t\"github.com/PumpkinSeed/npc/lib/common\"\n\t\"github.com/PumpkinSeed/npc/lib/consumer\"\n\t\"github.com/PumpkinSeed/npc/lib/producer\"\n\tnsq \"github.com/nsqio/go-nsq\"\n)\n\nvar localNSQd = \"127.0.0.1:4150\"\n\nfunc main() {\n\tl := common.SingleLogger{}\n\n\tpConf := \u0026producer.Config{\n\t\tNSQConfig:   nsq.NewConfig(),\n\t\tNSQDAddress: localNSQd,\n\t\tLogger:      l,\n\t\tLogLevel:    nsq.LogLevelInfo,\n\t}\n\n\tcConf := \u0026consumer.Config{\n\t\tNSQConfig:   nsq.NewConfig(),\n\t\tNSQDAddress: localNSQd,\n\t\tLogger:      l,\n\t\tLogLevel:    nsq.LogLevelInfo,\n\t}\n\n\tm, err := npc.New(npc.Server).\n\t\tInit(pConf, cConf, \"request\", \"server\", common.SingleLogger{}).\n\t\tServer(\u0026app{})\n\n\tif err != nil {\n\t\tpanic(err)\n\t\treturn\n\t}\n\n\t// Start to listen as server\n\tm.Listen()\n}\n\ntype app struct{}\n\nfunc (a *app) Serve(ctx context.Context, method string, reqBuf []byte) ([]byte, error) {\n\tswitch method {\n\tcase \"Add\":\n\t\trsp := struct {\n\t\t\tZ int\n\t\t}{\n\t\t\tZ: 12,\n\t\t}\n\t\trspBuf, err := json.Marshal(rsp)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn rspBuf, nil\n\tdefault:\n\t\treturn nil, nil\n\t}\n}\n```\n\n### Client\n\nClient implements a publisher which waiting for the response until it's not arriving or the timeout not reached. \n\nCreate a client using the `npc.New({TYPE})`, `Init({PRODUCER_CONFIG}, {CONSUMER_CONFIG}, {REQUEST_TOPIC}, {NSQ_CHANNEL}, {LOGGER})` and the `Client({RESPONSE_TOPIC})`. The type in this case will be `npc.Client`. After call the `Publish({RESOURCE}, {DATA})` method. More information about the [details](#details) section.\n\n```\npackage main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/PumpkinSeed/npc\"\n\t\"github.com/PumpkinSeed/npc/lib/common\"\n\t\"github.com/PumpkinSeed/npc/lib/consumer\"\n\t\"github.com/PumpkinSeed/npc/lib/producer\"\n\tnsq \"github.com/nsqio/go-nsq\"\n)\n\nconst (\n\treqTopic = \"request\"  // topic for sending request to server\n\trspTopic = \"response\" // topic for getting responses from server\n\tchannel  = \"client\"   // channel name for rspTopic topic\n)\n\nvar localNSQd = \"127.0.0.1:4150\"\n\nfunc main() {\n\tvar wg sync.WaitGroup\n\n\trand.Seed(time.Now().UTC().UnixNano())\n\taction(\u0026wg)\n}\n\nfunc action(wg *sync.WaitGroup) {\n\tl := common.SingleLogger{}\n\n\tpConf := \u0026producer.Config{\n\t\tNSQConfig:   nsq.NewConfig(),\n\t\tNSQDAddress: localNSQd,\n\t\tLogger:      l,\n\t\tLogLevel:    nsq.LogLevelInfo,\n\t}\n\n\tcConf := \u0026consumer.Config{\n\t\tNSQConfig:   nsq.NewConfig(),\n\t\tNSQDAddress: localNSQd,\n\t\tLogger:      l,\n\t\tLogLevel:    nsq.LogLevelInfo,\n\t}\n\n\tm, err := npc.New(npc.Client).\n\t\tInit(pConf, cConf, \"request\", \"server\", l).\n\t\tClient(\"response\")\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tresp, err := m.Publish(\"Add\", []byte(\"test\"))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(string(resp))\n}\n```\n\n### Details\n\n**Logger**\n\nThe logger must implement the `common.Logger` interface, by default there is two predefined logger:\n\n- `common.BlankLogger`: Don't log anything\n- `common.SimpleLogger`: Log with `fmt.Println`, format the depth of the call and the message\n\n**Producer config**\n\nThe producer config supports the following options:\n\n```\ntype Config struct {\n\t// NSQConfig config for the consumer\n\tNSQConfig *nsq.Config\n\n\t// NSQDAddress address of the NSQ daemon\n\tNSQDAddress string\n\n\t// Logger of the consumer\n\tLogger common.Logger\n\n\t// LogLevel set the log level of the consumer\n\tLogLevel nsq.LogLevel\n}\n```\n\n**Consumer config**\n\nThe consumer config supports the following options:\n\n```\ntype Config struct {\n\t// NSQConfig config for the consumer\n\tNSQConfig *nsq.Config\n\n\t// NSQDAddress address of the NSQ daemon\n\tNSQDAddress string\n\n\t// NSQLookupdAddresses addresses of the NSQ Lookup daemons\n\tNSQLookupdAddresses []string\n\n\t// Concurrency amout of concurrent handlers of the consumer\n\tConcurrency int\n\n\t// Logger of the consumer\n\tLogger common.Logger\n\n\t// LogLevel set the log level of the consumer\n\tLogLevel nsq.LogLevel\n}\n```\n\n**AppServer**\n\nThe server of the RPC can have a user-defined server mechanism. It's waiting for an struct which implements the rpc.AppServer interface:\n\n```\ntype AppServer interface {\n\tServe(ctx context.Context, typ string, req []byte) ([]byte, error)\n}\n```\n\n**Interrupter**\n\nThe server have a default interrupter which stops the server in case of `Ctrl+C`, but the user can define an own interrupter and pass it into the server by the following method:\n\n```\nSetInterruptor(i func())\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpumpkinseed%2Fnpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpumpkinseed%2Fnpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpumpkinseed%2Fnpc/lists"}