dev vouch dev on at. thats about it
0
fork

Configure Feed

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

add counter task

Luna 4712c9c3 94f64c55

+81 -1
+2 -1
appview/lib/atvouch/application.ex
··· 10 10 children = 11 11 repos() ++ 12 12 [ 13 - {Bandit, plug: Atvouch.Router, port: port, ip: {127, 0, 0, 1}} 13 + {Bandit, plug: Atvouch.Router, port: port, ip: {127, 0, 0, 1}}, 14 + Atvouch.Tinycron.new(Atvouch.CounterTask, every: 60, jitter: -5..5) 14 15 ] ++ tap_children() 15 16 16 17 opts = [strategy: :one_for_one, name: Atvouch.Supervisor]
+14
appview/lib/atvouch/counter_task.ex
··· 1 + defmodule Atvouch.CounterTask do 2 + require Logger 3 + use Prometheus.Metric 4 + 5 + def tick do 6 + identities_count = Atvouch.Repo.aggregate(Atvouch.Identity, :count) 7 + vouches_count = Atvouch.Repo.aggregate(Atvouch.Vouch, :count) 8 + 9 + Gauge.set([name: :identities_total], identities_count) 10 + Gauge.set([name: :vouches_total], vouches_count) 11 + 12 + Logger.debug("counters: identities=#{identities_count} vouches=#{vouches_count}") 13 + end 14 + end
+10
appview/lib/atvouch/telemetry.ex
··· 21 21 labels: [:method, :route, :status] 22 22 ) 23 23 24 + Gauge.declare( 25 + name: :identities_total, 26 + help: "Total number of identities" 27 + ) 28 + 29 + Gauge.declare( 30 + name: :vouches_total, 31 + help: "Total number of vouches" 32 + ) 33 + 24 34 :telemetry.attach( 25 35 @handler_id, 26 36 [:bandit, :request, :stop],
+55
appview/lib/atvouch/tinycron.ex
··· 1 + defmodule Atvouch.Tinycron do 2 + use GenServer 3 + require Logger 4 + 5 + def new(module, opts \\ []) do 6 + %{ 7 + id: module, 8 + start: {__MODULE__, :start_link, [module, opts |> Keyword.put(:name, module)]} 9 + } 10 + end 11 + 12 + def start_link(module, opts \\ []) do 13 + GenServer.start_link(__MODULE__, [module, opts], opts) 14 + end 15 + 16 + def noop(mod, value) do 17 + GenServer.cast(mod, {:noop, value}) 18 + end 19 + 20 + @impl true 21 + def init([module, opts]) do 22 + state = %{module: module, opts: opts} 23 + schedule_work(state) 24 + {:ok, state} 25 + end 26 + 27 + @impl true 28 + def handle_info(:work, %{module: module} = state) do 29 + unless state |> Map.get(:noop, false) do 30 + Logger.debug("running #{inspect(state.module)}") 31 + module.tick() 32 + end 33 + 34 + schedule_work(state) 35 + {:noreply, state} 36 + end 37 + 38 + @impl true 39 + def handle_cast({:noop, value}, state) do 40 + {:noreply, state |> Map.put(:noop, value)} 41 + end 42 + 43 + defp schedule_work(state) do 44 + every_seconds = state.opts |> Keyword.get(:every) || 10 45 + jitter_seconds_range = state.opts |> Keyword.get(:jitter) || -2..2 46 + first..last//step = jitter_seconds_range 47 + # turn it into milliseconds for greater jitter possibilities 48 + jitter_milliseconds_range = (first * 1000)..(last * 1000)//step 49 + 50 + # prevent jitter from creating negative next_tick_time by doing max(0, next_tick_time) 51 + next_tick_time = max(0, every_seconds * 1000 + Enum.random(jitter_milliseconds_range)) 52 + Logger.debug("scheduling #{inspect(state.module)} in #{next_tick_time}ms") 53 + Process.send_after(self(), :work, next_tick_time) 54 + end 55 + end