{"id":22511156,"url":"https://github.com/renderedtext/fun-registry","last_synced_at":"2026-02-24T21:32:39.763Z","repository":{"id":137211794,"uuid":"127451978","full_name":"renderedtext/fun-registry","owner":"renderedtext","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-20T15:24:44.000Z","size":15,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-08-18T20:47:04.445Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","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/renderedtext.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-30T16:56:10.000Z","updated_at":"2025-02-27T00:26:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"9c93b0e9-451c-4344-ac6d-f9a5e5ece7ee","html_url":"https://github.com/renderedtext/fun-registry","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/renderedtext/fun-registry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renderedtext%2Ffun-registry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renderedtext%2Ffun-registry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renderedtext%2Ffun-registry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renderedtext%2Ffun-registry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/renderedtext","download_url":"https://codeload.github.com/renderedtext/fun-registry/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renderedtext%2Ffun-registry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29801021,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-24T21:02:39.706Z","status":"ssl_error","status_checked_at":"2026-02-24T21:02:21.834Z","response_time":75,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-12-07T02:09:41.691Z","updated_at":"2026-02-24T21:32:39.747Z","avatar_url":"https://github.com/renderedtext.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FunRegistry - Function Registry\n\nA dynamic function registry, useful for implementing processes that can be\nmodified during their lifetime.\n\nAn example use case is the creation of fake GRPC that emulates remote servers.\nThis is useful in development and test environments.\n\n## Installation\n\nAdd the following to your mixfile:\n\n```elixir\ndef deps do\n  [\n    {:fun_registry, github: \"renderedtext/fun-registry\", only: [:dev, :test]}\n  ]\nend\n```\n\n## Example usage for creating fake GRPC servers\n\nFirst, we will create a fake server that emulates a remote Calculator service:\n\n``` elixir\ndefmodule CalculatorService do\n  use GRPC.Server, service: Calculator.Service\n\n  def add(req, stream) do\n    # instead of an implementation, we will relly on the FunRegistry\n    # to fetch and run a function\n\n    FunRegistry.run(__MODULE__, :add, [req, stream])\n  end\nend\n\nGRPC.Server.start(CalculatorService, 50051)\n```\n\nLet's connect to the calculator service and invoke some rpc methods:\n\n``` elixir\ndef calculate_remotly(a, b) do\n  #\n  # in dev and test this is set to \"localhost:50051\"\n  # in prod we will connect to a real server\n  #\n  endpoint = Application.get_env(:my_app, :calculator_endpoint)\n\n  {:ok, channel} = GRPC.Server.connect(endpoint)\n\n  req = Calculator.AddRequest.new(a: 12, b: 13)\n\n  {:ok, res} = Calculator.Stub.add(req)\n\n  res.result\nend\n```\n\nNow, we can use the function registry to simulate the behaviour of the remote\nserver:\n\n``` elixir\nsetup do\n  FunRegistry.clear!\nend\n\ntest \"calculate-remotly is able to communicate with remote servers\" do\n  # first, we will stub the behaviour of the server\n  FunRegistry.set!(CalculatorService, :add, fn(req, _) -\u003e\n    Calculator.AddResponse.new(result: req.a + req.b)\n  end)\n\n  assert calculate_remotly(1, 2) == 10\nend\n\ntest \"calculate-remotly is able to communicate with remote servers stubbed version\" do\n  # instead of functions, we can set a stubbed response directly\n  FunRegistry.set!(CalculatorService, :add, Calculator.AddResponse.new(result: 10))\n\n  assert calculate_remotly(1, 2) == 10\nend\n\ntest \"calculate-remotly passes the correct data to the remote service\" do\n  # we will store the values in an agent\n  {:ok, agent} = Agent.new(fn -\u003e nil end)\n\n  # instead of functions, we can set a stubbed response directly\n  FunRegistry.set!(CalculatorService, :add, fun(req, _) -\u003e\n    Agent.update(agent, fn state -\u003e {req.a, req.b} end)\n  end)\n\n  # execute the remote call\n  calculate_remotly(1, 2) == 10\n\n  # fetch the data that was received by the remote server\n  values = Agent.get(agent, pid, fn s -\u003e s end)\n\n  # make sure that the remote server got the correct info\n  assert values == {1, 2}\nend\n\ntest \"calculate service is too slow\" do\n  # first, we will stub the behaviour of the server\n  FunRegistry.set!(CalculatorService, :add, fun(_, _) -\u003e\n    :timer.sleep(5000)\n  end)\n\n  assert_raise fn -\u003e calculate_remotly(1, 2) end)\nend\n\ntest \"calculate service is broken\" do\n  # first, we will stub the behaviour of the server\n  FunRegistry.set!(CalculatorService, :add, fun(_, _) -\u003e\n    raise \"I don't feel well\"\n  end)\n\n  assert_raise fn -\u003e calculate_remotly(1, 2) end)\nend\n```\n\n## License\n\nThis software is licensed under [the Apache 2.0 license](LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenderedtext%2Ffun-registry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenderedtext%2Ffun-registry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenderedtext%2Ffun-registry/lists"}