diff options
author | Hubert Chathi <hubert@uhoreg.ca> | 2020-08-29 22:28:04 -0400 |
---|---|---|
committer | Hubert Chathi <hubert@uhoreg.ca> | 2020-08-29 22:43:12 -0400 |
commit | 126ff42d912dfea9e251e2b98bdcf8f295b8707e (patch) | |
tree | 5820307fc63e643e36b9534686c3585d5ad3b346 /lib/polyjuice/client.ex | |
parent | add module for handling .well-known (diff) |
make Polyjuice.Client.start_link return {:ok, pid}, like a normal start_link
add a function that returns a client struct from the pid, and add a stop
function to Polyjuice.Client.stop
Diffstat (limited to 'lib/polyjuice/client.ex')
-rw-r--r-- | lib/polyjuice/client.ex | 91 |
1 files changed, 64 insertions, 27 deletions
diff --git a/lib/polyjuice/client.ex b/lib/polyjuice/client.ex index 9f4aa8f..3f1668c 100644 --- a/lib/polyjuice/client.ex +++ b/lib/polyjuice/client.ex @@ -16,10 +16,7 @@ defmodule Polyjuice.Client do @moduledoc """ Matrix client functions. - To start a client, use `start_link/2`, and to stop it, use - `stop/3`. - - The struct in this module, or any struct that implements the + The client created by this module, or any client that implements the `Polyjuice.Client.API` protocol, can be used to connect to a Matrix server using the functions from submodules. @@ -31,7 +28,23 @@ defmodule Polyjuice.Client do The client defined in this module should work for most cases. If you want more control, you can use `Polyjuice.Client.LowLevel` instead. + To start a client with this module, create a process using `start_link/2`, + and then call `get_client/1` to get a struct that can be used with the above + modules. To stop the client, use `Polyjuice.Client.API.stop/3`. + """ + + @doc """ + Returns a specification to start the client. + + `arg` must be a list, where the first element is the base URL for the + homeserver, and the remainder of the list is options, as would be given to + `start_link/2`. For example: + + Polyjuice.Client.child_spec(["http://localhost:8008", sync: false]) + + """ + use Supervisor require Logger @typedoc """ @@ -81,14 +94,29 @@ defmodule Polyjuice.Client do will not start if there is no `storage` or `handler` provided. - `sync_filter`: the filter to use for the sync. Defaults to no filter. """ - @spec start_link(base_url :: String.t(), opts :: Keyword.t()) :: t() - def start_link(base_url, opts \\ []) when is_binary(base_url) and is_list(opts) do + @spec start_link(base_url :: String.t(), opts :: Keyword.t()) :: {:ok, pid} + def start_link(base_url, opts) when is_binary(base_url) and is_list(opts) do base_url = if(String.ends_with?(base_url, "/"), do: base_url, else: base_url <> "/") |> URI.parse() client_id = Agent.get_and_update(Polyjuice.Client.ID, &{&1, &1 + 1}) + Supervisor.start_link( + __MODULE__, + [client_id, base_url, opts], + name: process_name(client_id, :supervisor) + ) + end + + def start_link(base_url) when is_binary(base_url), do: start_link(base_url, []) + + def start_link([base_url | opts]) when is_binary(base_url) and is_list(opts) do + start_link(base_url, opts) + end + + @impl Supervisor + def init([client_id, base_url, opts]) do sync = Keyword.get(opts, :sync, true) storage = Keyword.get(opts, :storage) handler = Keyword.get(opts, :handler) @@ -153,7 +181,16 @@ defmodule Polyjuice.Client do %{ access_token: access_token, user_id: user_id, - device_id: device_id + device_id: device_id, + client: %__MODULE__{ + base_url: base_url, + id: client_id, + storage: storage, + handler: handler, + sync: sync, + opts: opts, + test: Keyword.get(opts, :test, false) + } } end, [name: process_name(client_id, :state)] @@ -165,29 +202,19 @@ defmodule Polyjuice.Client do ) ] - {:ok, _pid} = - Supervisor.start_link(children, - strategy: :rest_for_one, - name: process_name(client_id, :supervisor) - ) - - %__MODULE__{ - base_url: base_url, - id: client_id, - storage: storage, - handler: handler, - sync: sync, - opts: opts, - test: Keyword.get(opts, :test, false) - } + Supervisor.init(children, strategy: :rest_for_one) end @doc """ - Stop a client. + Get a struct that implements `Polyjuice.Client.API` from the pid given by + `start_link`. """ - @spec stop(Polyjuice.Client.t(), reason :: term, timeout()) :: :ok - def stop(%__MODULE__{id: id}, reason \\ :normal, timeout \\ :infinity) do - Supervisor.stop(process_name(id, :supervisor), reason, timeout) + def get_client(pid) do + agent_pid = + Supervisor.which_children(pid) + |> Enum.find_value(fn {id, pid, _, _} -> if id == Polyjuice.Client, do: pid end) + + Agent.get(agent_pid, &Map.fetch!(&1, :client)) end @doc false @@ -244,6 +271,12 @@ defmodule Polyjuice.Client do """ @spec transaction_id(client_api :: Polyjuice.Client.API.t()) :: String.t() def transaction_id(client_api) + + @doc """ + Stop the client. + """ + @spec stop(Polyjuice.Client.t(), reason :: term, timeout()) :: :ok + def stop(client_api, reason \\ :normal, timeout \\ :infinity) end defimpl Polyjuice.Client.API do @@ -369,6 +402,10 @@ defmodule Polyjuice.Client do def transaction_id(_) do "#{Node.self()}_#{:erlang.system_time(:millisecond)}_#{:erlang.unique_integer()}" end + + def stop(%{id: id}, reason \\ :normal, timeout \\ :infinity) do + Supervisor.stop(Polyjuice.Client.process_name(id, :supervisor), reason, timeout) + end end @doc false @@ -518,7 +555,7 @@ defmodule Polyjuice.Client do ) end - if client.sync do + if client.sync && client.handler do # make sure we don't already have a sync process running kill_sync(client.id) |