Skip to content

qhwa/formular-client

Repository files navigation

Formular.Client

codecov

This package brings the ability to update the Elixir modules on the fly.

The idea is to have the formular code hosted on a central server, and watch them. Formulas will be compiled into Elixir modules with the help of this package, as the following diagram depicts:

      Users
        │
        │uses
        │
        ▼

      │my application                                      Formular Server
┌─────┴──────────────────┐                          ┌──────────────────────────┐
│                        │                          │                          │
│ MyMod1    ┌──────────┐ │         watches          │   "my function code 1"   │
│ MyMod2    │Formular  └─┼──────────────────────────►   "my function code 2"   │
│ MyMod3◄───┤Client    ◄─┼──────────────────────────┐   "my function code 3"   │
│ ...       └──────────┘ │                          │   ...                    │
│                        │                          │                          │
└────────────────────────┘                          └──────────▲───────────────┘
                                                               │
                                                               │ updates
                                                               │
                                                               │

                                                           Developer

The code is compiled and run under security constraints by Formular.

Getting Start

  1. Install dependency

    Add {:formular_client, "~> 0.2.1"} to deps section of mix.exs

  2. Config client

    Add formular client into the supervision tree:

    # file: lib/myapp/application.ex
    
    defmodule Myapp.Application do
      use Application
    
      def start(_type, _args) do
        children = [
          ...
          {Formular.Client.Supervisor, formular_client_config()},
          ...
        ]
    
        opts = [strategy: :one_for_one, name: QuestService.Supervisor]
        Supervisor.start_link(children, opts)
      end
    
      defp formular_client_config,
        do: Application.get_env(:my_app, :formular_client)
    end
    # file: config/config.exs
    
    config :my_app, :formular_client,
      client_name: "myapp",
      url: "wss://example.com/socket/websocket",
      formulas: [
        # format 1: binary key
        "my-formula-1",
        # format 2: {module to compile, key}
        {MyMod2, "my-formula-2"},
        # format 3: {module, key, context_module}
        {MyMod3, "my-formula-3", MyHelperModule}
      ]

    where url points to a formular server.

  3. Use it in your code

    iex> Formular.Client.eval("my-formula-1", [])
    {:ok, false}

Testing support

You can use Formular.Client.Adapter.Mock for testing.

# file: config/test.exs
config :my_app, :formular_client,
  :adapter: {
    Formular.Client.Adapter.Mock,
    formulars: [
      {"my-formula-1", fn _binding, _opts -> :foo end}
    ]
  }

Optionally, to change the return value for a formula dynamically, you can call Formular.Client.Adapter.Mock.mock_global/2 as the following:

defmodule MyTestCase do
  import Formular.Client.Adapter.Mock

  test "my test case" do
    mock_global("my-formula-1", fn _binding, _opts -> :bar end)

    # testing goes here...
  end
end

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Languages