summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHubert Chathi <hubert@uhoreg.ca>2020-08-29 22:28:04 -0400
committerHubert Chathi <hubert@uhoreg.ca>2020-08-29 22:43:12 -0400
commit126ff42d912dfea9e251e2b98bdcf8f295b8707e (patch)
tree5820307fc63e643e36b9534686c3585d5ad3b346 /lib
parentadd 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')
-rw-r--r--lib/mix/tasks/polyjuice/login.ex6
-rw-r--r--lib/mix/tasks/polyjuice/logout.ex6
-rw-r--r--lib/polyjuice/client.ex91
-rw-r--r--lib/polyjuice/client/low_level.ex5
4 files changed, 77 insertions, 31 deletions
diff --git a/lib/mix/tasks/polyjuice/login.ex b/lib/mix/tasks/polyjuice/login.ex
index 3ae1234..f485ed5 100644
--- a/lib/mix/tasks/polyjuice/login.ex
+++ b/lib/mix/tasks/polyjuice/login.ex
@@ -51,16 +51,18 @@ defmodule Mix.Tasks.Polyjuice.Login do
nil
end
- client =
+ {:ok, client_pid} =
Polyjuice.Client.start_link(
url,
storage: storage,
sync: false
)
+ client = Polyjuice.Client.get_client(client_pid)
+
ret = Polyjuice.Client.log_in_with_password(client, user_id, password)
- Polyjuice.Client.stop(client)
+ Polyjuice.Client.API.stop(client)
if storage, do: Polyjuice.Client.Storage.close(storage)
diff --git a/lib/mix/tasks/polyjuice/logout.ex b/lib/mix/tasks/polyjuice/logout.ex
index 9ac65a3..71f0e4d 100644
--- a/lib/mix/tasks/polyjuice/logout.ex
+++ b/lib/mix/tasks/polyjuice/logout.ex
@@ -54,7 +54,7 @@ defmodule Mix.Tasks.Polyjuice.Logout do
nil
end
- client =
+ {:ok, client_pid} =
Polyjuice.Client.start_link(
url,
access_token: opts[:access_token],
@@ -62,9 +62,11 @@ defmodule Mix.Tasks.Polyjuice.Logout do
sync: false
)
+ client = Polyjuice.Client.get_client(client_pid)
+
ret = Polyjuice.Client.log_out(client)
- Polyjuice.Client.stop(client)
+ Polyjuice.Client.API.stop(client)
if storage, do: Polyjuice.Client.Storage.close(storage)
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)
diff --git a/lib/polyjuice/client/low_level.ex b/lib/polyjuice/client/low_level.ex
index 918805e..f41cf8c 100644
--- a/lib/polyjuice/client/low_level.ex
+++ b/lib/polyjuice/client/low_level.ex
@@ -109,6 +109,11 @@ defmodule Polyjuice.Client.LowLevel do
def transaction_id(_) do
"#{Node.self()}_#{:erlang.system_time(:millisecond)}_#{:erlang.unique_integer()}"
end
+
+ def stop(_, _, _) do
+ # don't need to do anything to stop it
+ :ok
+ end
end
@doc """