this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add send_after

garrison ddfc0400 29a26887

+43 -6
+18 -6
lib/trinity/scheduler.ex
··· 1 1 defmodule Trinity.Scheduler do 2 + alias Trinity.SimProcess 2 3 alias Trinity.Scheduler.SimulationSupervisor 3 4 4 5 defmodule Simulation do ··· 259 260 end 260 261 end 261 262 263 + def handle_send_after(dest, message, time) do 264 + %{queue: queue, now: now} = get_sim() 265 + enqueue_event(queue, now, time, {:send_after, dest, message}) 266 + end 267 + 262 268 defp perform_next(queue, proc_queue_keys, now) do 263 - case pop_next(queue, proc_queue_keys) do 264 - {time, {_event, pid, ref}} -> 269 + case pop_next(queue) do 270 + {time, {:timeout, pid, ref}} -> 271 + :ets.delete(proc_queue_keys, pid) 272 + set_now(now, time) 273 + send pid, ref 274 + {time, {:resume, pid, ref}} -> 275 + :ets.delete(proc_queue_keys, pid) 265 276 set_now(now, time) 266 277 send pid, ref 278 + {time, {:send_after, dest, message}} -> 279 + set_now(now, time) 280 + SimProcess.perform_send(dest, message) 281 + perform_next(queue, proc_queue_keys, now) 267 282 end 268 283 end 269 284 270 - defp pop_next(queue, proc_queue_keys) do 285 + defp pop_next(queue) do 271 286 case :ets.next_lookup(queue, {-1, 0}) do 272 287 {_, [{{time, _i} = key, entry}]} -> 273 288 :ets.delete(queue, key) 274 - {_event, pid, _ref} = entry 275 - :ets.delete(proc_queue_keys, pid) 276 - 277 289 {time, entry} 278 290 _ -> 279 291 raise "Queue empty!"
+20
lib/trinity/sim_process.ex
··· 18 18 end 19 19 end 20 20 21 + @spec send_after(pid | atom, term, non_neg_integer) :: term 22 + def send_after(dest, message, time) do 23 + case get_sim() do 24 + nil -> Process.send_after(dest, message, time) 25 + _sim -> sim_send_after(dest, message, time) 26 + end 27 + end 28 + 21 29 @spec node :: node 22 30 def node do 23 31 case get_sim() do ··· 95 103 96 104 [] -> raise ArgumentError, "Invalid destination #{inspect(name_node)}" 97 105 end 106 + end 107 + 108 + # For use by Scheduler processing :send_after events 109 + @doc false 110 + def perform_send(dest, message) do 111 + sim_send(dest, message) 112 + end 113 + 114 + defp sim_send_after(dest, message, time) do 115 + Scheduler.handle_send_after(dest, message, time) 116 + # Real send_after returns a timer ref, but it's probably not worth the overhead 117 + nil 98 118 end 99 119 100 120 defp sim_alias do
+5
test/trinity_test.exs
··· 88 88 assert result == (id + 10) 89 89 end) 90 90 91 + SimProcess.send_after self(), :finish, 1000 92 + receive_yield do 93 + :finish -> dbg "finished" 94 + end 95 + 91 96 Scheduler.yield(1000) 92 97 #dbg Scheduler.dump(), limit: :infinity 93 98 end)