@@ -3,17 +3,16 @@ defmodule Quantum.TaskRegistry do
33
44 # Registry to check if a task is already running on a node.
55
6- use GenServer
7-
86 require Logger
97
10- alias __MODULE__ . { InitOpts , StartOpts , State }
8+ alias __MODULE__ . StartOpts
9+ alias Quantum.Job
1110
1211 # Start the registry
1312 @ spec start_link ( StartOpts . t ( ) ) :: GenServer . on_start ( )
14- def start_link ( % StartOpts { name: name } ) do
15- __MODULE__
16- |> GenServer . start_link ( % InitOpts { } , name: name )
13+ def start_link ( % StartOpts { name: name , listeners: listeners } ) do
14+ [ keys: :unique , name: name , listeners: listeners ]
15+ |> Registry . start_link ( )
1716 |> case do
1817 { :ok , pid } ->
1918 { :ok , pid }
@@ -27,114 +26,44 @@ defmodule Quantum.TaskRegistry do
2726 end
2827 end
2928
29+ @ spec child_spec ( options :: StartOpts . t ( ) ) :: Supervisor . child_spec ( )
30+ def child_spec ( options ) ,
31+ do:
32+ [ ]
33+ |> Registry . child_spec ( )
34+ |> Map . put ( :start , { __MODULE__ , :start_link , [ options ] } )
35+
3036 # Mark a task as Running
3137 #
3238 # ### Examples
3339 #
34- # iex> Quantum.TaskRegistry.mark_running(server, running_job.name, self())
40+ # iex> Quantum.TaskRegistry.mark_running(server, running_job.name, Node. self())
3541 # :already_running
3642 #
37- # iex> Quantum.TaskRegistry.mark_running(server, not_running_job.name, self())
43+ # iex> Quantum.TaskRegistry.mark_running(server, not_running_job.name, Node. self())
3844 # :marked_running
45+ @ spec mark_running ( server :: atom , task :: Job . name ( ) , node :: Node . t ( ) ) ::
46+ :already_running | :marked_running
3947 def mark_running ( server , task , node ) do
40- GenServer . call ( server , { :running , task , node } )
48+ server
49+ |> Registry . register ( { task , node } , true )
50+ |> case do
51+ { :ok , _pid } -> :marked_running
52+ { :error , { :already_registered , _other_pid } } -> :already_running
53+ end
4154 end
4255
4356 # Mark a task as Finished
4457 #
4558 # ### Examples
4659 #
47- # iex> Quantum.TaskRegistry.mark_running(server, running_job.name, self())
60+ # iex> Quantum.TaskRegistry.mark_running(server, running_job.name, Node. self())
4861 # :ok
4962 #
50- # iex> Quantum.TaskRegistry.mark_running(server, not_running_job.name, self())
63+ # iex> Quantum.TaskRegistry.mark_running(server, not_running_job.name, Node. self())
5164 # :ok
65+ @ spec mark_finished ( server :: atom , task :: Job . name ( ) , node :: Node . t ( ) ) :: :ok
5266 def mark_finished ( server , task , node ) do
53- GenServer . cast ( server , { :finished , task , node } )
54- end
55-
56- # Query if a task with given name is running
57- #
58- # ### Examples
59- #
60- # iex> Quantum.TaskRegistry.is_running?(server, running_job.name)
61- # true
62- #
63- # iex> Quantum.TaskRegistry.is_running?(server, not_running_job.name)
64- # false
65- def is_running? ( server , task ) do
66- GenServer . call ( server , { :is_running? , task } )
67- end
68-
69- # Query if any tasks are running in the cluster
70- #
71- # ### Examples
72- #
73- # iex> Quantum.TaskRegistry.any_running?(server_with_running_tasks)
74- # true
75- #
76- # iex> Quantum.TaskRegistry.any_running?(server_without_running_tasks)
77- # false
78- def any_running? ( server ) do
79- GenServer . call ( server , :any_running? )
80- end
81-
82- @ impl GenServer
83- def init ( % InitOpts { } ) do
84- { :ok , % State { running_tasks: % { } } }
85- end
86-
87- @ impl GenServer
88- def handle_call ( { :running , task , node } , _caller , % State { running_tasks: running_tasks } = state ) do
89- if Enum . member? ( Map . get ( running_tasks , task , [ ] ) , node ) do
90- { :reply , :already_running , state }
91- else
92- { :reply , :marked_running ,
93- % { state | running_tasks: Map . update ( running_tasks , task , [ node ] , & [ node | & 1 ] ) } }
94- end
95- end
96-
97- @ impl GenServer
98- def handle_call ( { :is_running? , task } , _caller , % State { running_tasks: running_tasks } = state ) do
99- case running_tasks do
100- % { ^ task => [ _ | _ ] } ->
101- { :reply , true , state }
102-
103- % { ^ task => [ ] } ->
104- { :reply , false , state }
105-
106- % { } ->
107- { :reply , false , state }
108- end
109- end
110-
111- @ impl GenServer
112- def handle_call ( :any_running? , _caller , % State { running_tasks: running_tasks } = state ) do
113- if Enum . empty? ( running_tasks ) do
114- { :reply , false , state }
115- else
116- { :reply , true , state }
117- end
118- end
119-
120- @ impl GenServer
121- def handle_cast ( { :finished , task , node } , % State { running_tasks: running_tasks } = state ) do
122- running_tasks =
123- running_tasks
124- |> Map . update ( task , [ ] , & ( & 1 -- [ node ] ) )
125- |> case do
126- % { ^ task => [ ] } = still_running_tasks ->
127- Map . delete ( still_running_tasks , task )
128-
129- still_running_tasks ->
130- still_running_tasks
131- end
132-
133- { :noreply , % { state | running_tasks: running_tasks } }
134- end
135-
136- @ impl GenServer
137- def handle_info ( _message , state ) do
138- { :noreply , [ ] , state }
67+ Registry . unregister ( server , { task , node } )
13968 end
14069end
0 commit comments