{"id":20743083,"url":"https://github.com/aimingoo/ngx_4c","last_synced_at":"2026-03-01T03:03:15.335Z","repository":{"id":36373359,"uuid":"40678205","full_name":"aimingoo/ngx_4c","owner":"aimingoo","description":"n4c programming architecture, the Controllable, Computable and Communication Cluster in nginx.","archived":false,"fork":false,"pushed_at":"2015-12-03T23:43:59.000Z","size":50,"stargazers_count":9,"open_issues_count":0,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-08-07T01:30:59.157Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aimingoo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-13T19:36:49.000Z","updated_at":"2020-02-21T06:13:32.000Z","dependencies_parsed_at":"2022-09-06T06:21:50.406Z","dependency_job_id":null,"html_url":"https://github.com/aimingoo/ngx_4c","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/aimingoo/ngx_4c","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimingoo%2Fngx_4c","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimingoo%2Fngx_4c/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimingoo%2Fngx_4c/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimingoo%2Fngx_4c/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aimingoo","download_url":"https://codeload.github.com/aimingoo/ngx_4c/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimingoo%2Fngx_4c/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29959284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T01:47:18.291Z","status":"online","status_checked_at":"2026-03-01T02:00:07.437Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-11-17T07:09:01.409Z","updated_at":"2026-03-01T03:03:15.297Z","avatar_url":"https://github.com/aimingoo.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ngx_4c\nn4c programming architecture, a Controllable, Computable and Communication Cluster implementation in nginx.\n\nn4c depend ngx_cc to build communication cluster, use Multi-cast events drive application framework. it invoke by nginx phases, and built-in standard API in the framework.\n\nabout N4C architecture  @see [n4c project](https://github.com/aimingoo/n4c).\n\nmain features:\n- events - very simple, cool!\n- consistency event loop\n- simple and extendible location route\n- ngx_cc integrated, support cluster communication\n- modular application framework, scripting and dynamic loadding\n\n###Table of Contents\n  * [Install \u0026amp; Usage](#install--usage)\n  * [Events and event loop](#events-and-event-loop)\n  * [ngx_cc integrated](#ngx_cc-integrated)\n  * [PEDT: Distribution task module](#pedt-distribution-task-module)\n  * [N4C standard interfaces](#n4c-standard-interfaces)\n  * [N4C core framework](#n4c-core-framework)\n  * [Customizable headers in ngx_cc, or sub-request](#customizable-headers-in-ngx_cc-or-sub-request)\n  * [Event handles](#event-handles)\n  * [History](#history)\n\n# Install \u0026 Usage\nif need ngx_cc integrate, you must recomplie nginx. the detail in here: [ngx_cc environment requirements](https://github.com/aimingoo/ngx_cc#environment). no dependency require of other case.\n\nfor ngx_cc integrated, please try [test in the nginx environment](https://github.com/aimingoo/ngx_cc#4-test-in-the-nginx-environment) first, and clone the ngx_4c project from github, get all sub-modules.\n```bash\n\u003e cd ~\n\u003e git clone https://github.com/aimingoo/ngx_4c\n\n\u003e cd ~/ngx_4c/lib\n\u003e bash ./SUB_MODULES.sh\n```\nand run testcase:\n```bash\n#(into builded nginx directory)\n# run bin/nginx with -p parament to set prefix\n#\t- will start nginx with $prefix/conf/nginx.conf by default\n\u003e sudo sbin/nginx -p \"${HOME}/ngx_4c/nginx\"\n```\n\u003e note1: add these paths to nginx.conf in your project:\n\u003e * $prefix../?.lua;\n\u003e * $prefix../lib/?.lua;\n\n\u003e note2: if require other module(ex: ngx_cc or tundrawolf), push them to $(ngx_4c)/lib/, and append paths into nginx.conf:\n\u003e * $prefix../lib/ngx_cc/?.lua;\n\u003e * $prefix../lib/tundrawolf/?.lua;\n\n# Events and event loop\nthe Events is a lua module, it's multi-cast, multi-handles and lightweight event framework. @see:\n\u003e\t[https://github.com/aimingoo/Events](https://github.com/aimingoo/Events)\n\nin ngx_4c, the event loop drive by nginx phases. there is workflow for the loop:\n![n4c event loop](https://github.com/aimingoo/ngx_cc/wiki/images/n4c_event_loop.png)\n\nnext demo use ngx_4c as a web application framework.\n\n - nginx.conf\n\n```conf\nhttp {\n\t## path\u0026dict config\n\tlua_package_path ...;\n\n\t## n4c core framework and runtime\n\t# ------------------------------------\n\t# init global n4c setting and n4c.startWorker() launcher\n\tinit_by_lua_file 'init.lua';\n\n\t# init for per-worker\n\tinit_worker_by_lua 'n4c.startWorker();';\t# -- Init Worker Processes\n\n\t# standard handles\n\trewrite_by_lua 'n4c.doRequestBegin();';\t\t# -- On Request Begin\n\tbody_filter_by_lua 'n4c.doBodyFilter();';\t# -- On Response Chunks Filter\n\tlog_by_lua 'n4c.doSessionClose();';\t\t\t# -- On Request End and Close Session \n\t# ------------------------------------\n\n\tserver {\n\t\tlisten 80;\n\t}\n}\n```\n\n - init.lua\n\n```lua\nn4c = {}\nn4c.startWorker = function()\n\t-- NGX_4C launcher, with multicast events\n\tlocal events = require('lib.Events'):new()\n\trequire('ngx_4c').apply(n4c, events)\n\n\tevents.on('RequestBegin', function(uri, method, params)\n\t\tif uri == '/hello' then\n\t\t\tngx.say('hello, world.')\n\t\tend\n\tend)\n\n\tevents.on('RequestBegin', function(uri, method, params)\n\t\tif uri == '/hi' then\n\t\t\tngx.say('hi, ' .. params.name or 'guest')\n\t\tend\n\tend)\nend\n```\n\n- run and test\n\n```bash\n# start nginx\n# \t\u003e sudo sbin/nginx -c ...\n\n\u003e curl 'http://localhost/hello'\nhello, world.\n\n\u003e curl 'http://localhost/hi'\nhi, guest\n\n\u003e curl 'http://localhost/hi?name=aimingoo'\nhi, aimingoo\n```\n\n# ngx_cc integrated\n\n(1) insert ngx_cc standard config\n- see: $(ngx_4c)/nginx/conf/nginx.conf\n- see: [enable per-worker for listen](https://github.com/aimingoo/ngx_cc#4-test-in-the-nginx-environment)\n- see: [ngx_cc locations](https://github.com/aimingoo/ngx_cc#locations-in-nginxconf)\n\n(2) standard init.lua\n- see: $(ngx_4c)/init.lua\n\n(3) put webapp_demo.lua to $(ngx_4c)/scripts\n\n```lua\n-- /scripts/webapp_demo.lua\nlocal t = {}\nt.doRequestBegin = function(uri, method, params)\n\tif uri == '/test' then\n\t\tlocal atPerWorker, r_ok, r_resps = route.isInvokeAtPer();\n\t\tif atPerWorker then\n\t\t\tngx.say('hi, work at ', ngx.worker.pid())\n\t\telse\n\t\t\tngx_cc.say(r_ok, r_resps)\n\t\tend\n\tend)\nend\nreturn t\n```\n\nat last, add next line into init.lua\n```lua\nn4c.register(require('scripts.webapp_demo'))\n```\nand run test:\n```bash\n\u003e curl 'http://localhost/test'\nhi, work at xxxx\nhi, work at xxxx\nhi, work at xxxx\nhi, work at xxxx\n```\n# PEDT: Distribution task module\n\n(1) require tundrawolf project\n```bash\n\u003e cd lib\n\u003e run SUB_MODULES.sh\n```\n\n(2) update nginx.conf\n```conf\n.....\nlua_package_path '.....;$prefix../lib/tundrawolf/?.lua;;';\n```\n\n(3) load distribution task modules\n\u003e @see $(ngx_4c)/init.lua\n\n```lua\n...\n\t-- NGX_4C framework scripts extra - Distrbution task architecture\n\tn4c.register(require('scripts.n4cDistrbutionTaskNode'))\n\t-- n4c.register(require('scripts.n4cNodeTimer'))\n\trequire('module.n4c_executor').apply(route)\n\trequire('module.n4c_resource_node').apply(route)\n\n\t-- NGX_4C Distrbution task architecture - extended routes\n\tn4c:require('n4c.system.discoveries'):andThen(function(discoveries)\n\t\tmix(discoveries, require('routes.routes_ngxcc').new(n4c.configuration.default_channel_name), true)\n\tend)\n...\n```\n\n(4) testcase\nload test module, @see $(ngx_4c)/init.lua\n```conf\n...\n\t-- testcases, or more business processes\n\tn4c.register(require('testcase.t_pedt'))\n...\n```\nand test in shell:\n```bash\n\u003e # 1. test environment: install etcd and sandpiper for testcases\n\u003e brew install etcd etcdctl\n\u003e etcd\n\u003e cd ~\n\u003e git clone 'http://github.com/aimingoo/sandpiper'\n\u003e cd sandpiper\n\u003e npm install\n\u003e # 2. run sandpiper as daemon\n\u003e npm start\n\u003e # 3. start new shell, run again\n\u003e node testcase/t_tasks.js\n\n\u003e # 4. start new shell, and run nginx with test config.conf\n\u003e # \t- $(nginx_home) is home directory of nginx\n\u003e cd $(nginx_home)/sbin\n\u003e sudo nginx ./nginx -p \"${HOME}/ngx_4c/nginx\"\n\n\u003e # 5. run testcase\n\u003e curl -s 'http://localhost/n4c/test'\n[ {\n  \"a\": \"1\",\n  \"b\": \"2\",\n  \"c\": \"3\",\n  \"info\": \"HELLO\",\n  \"p1\": \"default value\"\n} ]\n\u003e curl -s 'http://localhost/n4c/system_routes'\n{\n  \"n4c.system.discoveries\": ::function::,\n  \"n4c:ngx_cc.N4C.registed.clients:*\": ::function::,\n  \"n4c:ngx_cc.N4C.registed.master:*\": ::function::,\n  \"n4c:ngx_cc.N4C.registed.super:*\": ::function::,\n  \"n4c:ngx_cc.N4C.registed.workers:*\": ::function::,\n  \"ngx_cc.N4C.registed.clients\": ::function::,\n  \"ngx_cc.N4C.registed.master\": ::function::,\n  \"ngx_cc.N4C.registed.super\": ::function::,\n  \"ngx_cc.N4C.registed.workers\": ::function::\n}\n```\n\n# N4C standard interfaces\n\n\u003e @see: $(ngx_4c)/ngx_4c.lua\n\n```lua\nn4c = {\n\t-- for ngx_cc\n\tconfiguration = {\n\t\tdefault_channel_name = 'N4C',\t-- channel name of ngx_cc\n\t\tmax_buffered_length = 4096,\t\t-- for n4c cached repsponse body\n\n\t\t-- more configuration of n4c expand or 3rd modules\n\t\tn4c_resource_group = '..',\n\t\tn4c_resource_notify_uri = '..',\n\t\tn4c_resource_query_uri = '..',\n\t\tn4c_execute_uri = '..',\n\t\tn4c_external_host = '..',\n\t\tetcd_server = { url = '..' },\n\t\t..\n\t},\n\tsuper = DEFAULT_CONIFG_SUPER,\t\t-- default is 127.0.0.1:80\n\n\t-- n4c worker launcher\n\tstartWorker = function() .. end,\n\n\t-- Events and event loop\n\tdoRequestBegin = function(uri, method, params) .. end,\n\tdoBodyFilter = function(chunk, eof) .. end,\n\tdoSessionClose = function() .. end,\n\n\t-- privated\n\tdoResponseEnd = function(uri, bodySize, buffered) .. end,\n\n\t-- utilities or helper\n\tstat = function() .. end,  -- return a stat object\n\tregister = function(scriptObject, ...) .. end, -- load scriptObject, and run main method with arguments\n}\n```\n\n# N4C core framework\n\n\u003e @see: $(ngx_4c)/scripts/n4cCoreFramework.lua\n\nthe core framework include features:\n- buffered response body\n - try 4k only, settings n4c.configuration.max_buffered_length\n- ngx.ctx.get_resp_object() will try return JSON object\n - lazy decode, high performances\n - result is cached in current request/session/context\n- implementation /channel_name/api?transferServer interface for ngx_cc\n\n# Customizable headers in ngx_cc, or sub-request\nwhen send sub-request in nginx.conf, you cant dynamic setting/update headers.\n\nbut, with ngx_4c, you can call ngx_cc to send a customizable headers to upstream by proxy_pass. the feature provided by \"n4c.doRequestBegin(true)\":\n```conf\n\tlocation ~ ^/([^/]+)/cast {\n\t\t...\n\n\t\t## n4c core: cc_headers custom support\n\t\trewrite_by_lua 'n4c.doRequestBegin(true);';\n\n\t\t...\n\t}\n```\nso, now, you call ngx_cc command with \"cc_headers\":\n```lua\nroute.cc(aUri, {\n\tdirection = 'workers',\n\tctx = {cc_headers = {\n\t\t[\"Accept-Language\"] = 'en-US',\n\t\t[\"Access-Control-Max-Age\"] = 24*3600\n\t}}\n})\n```\n\nor, use ngx.location.capture() without ngx_cc:\n```lua\nlocal aUri = '/test/headers'\nngx.location.capture(aUri, {\n\tctx = {cc_headers = { .. }}\n})\n```\nand, you must update nginx.conf for his location settings:\n```conf\n\tlocation /test/headers {\n\t\trewrite_by_lua 'n4c.doRequestBegin(true);';\n\t}\n```\n# Event handles\nplease handle Events by registed script module. the list of handles for per event:\n```text\ndoRequestBegin = function(uri, method, params)\n------ \n   doRequestBegin\n   doInternalRequestBegin\n\ndoBodyFilter = function(chunk, eof)\n------ \n   doBodyFilter\n   doInternalBodyFilter\n\ndoResponseEnd = function(uri, bodySize, buffered)\n------ \n   doResponseEnd\n   doInternalResponseEnd\n\ndoSessionClose = function()\n------ \n   doSessionClose\n   doInternalSessionClose\n```\nthe n4c.doResponseEnd() is privated, non publish interface but can handle it.\n\nplease read these cases for register handles:\n\n\u003e @see: $(ngx_4c)/scripts/*\n\u003e\n\u003e @see: $(ngx_4c)/testcase/t_nginx_phases.lua\n\n# History\n```text\n2015.11\trelease v0.9.1, support PEDT distribution task\n\t- require tundrawolf (a implement of PEDT specification )\n\t- support PEDT resource/task node\n\t- support ngx_cc node/worker processes as PEDT nodes\n\n2015.08\trelease v0.9.0\n\t- N4C programming architecture standard interfaces and examples\n\t- support ngx_cc integrated\n\t- support customizable headers for ngx_cc or sub-requests\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faimingoo%2Fngx_4c","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faimingoo%2Fngx_4c","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faimingoo%2Fngx_4c/lists"}