Packages
honeydew
1.4.1
1.5.0
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc7
1.0.0-rc6
1.0.0-rc5
1.0.0-rc4
1.0.0-rc3
1.0.0-rc2
1.0.0-rc1
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Pluggable local/clusterable job queue focused on safety.
Current section
Files
Jump to
Current section
Files
lib/honeydew/sources/ecto/sql/cockroach.ex
if Code.ensure_loaded?(Ecto) do
defmodule Honeydew.EctoSource.SQL.Cockroach do
@moduledoc false
alias Honeydew.EctoSource
alias Honeydew.EctoSource.SQL
alias Honeydew.EctoSource.State
@behaviour SQL
@impl true
def integer_type do
:bigint
end
@impl true
def table_name(schema) do
schema.__schema__(:source)
end
@impl true
def ready do
"CAST('#{SQL.far_in_the_past()}' AS TIMESTAMP)"
|> time_in_msecs
|> msecs_ago
end
@impl true
def delay_ready(state) do
"UPDATE #{state.table}
SET #{state.lock_field} = (#{ready()} + $1 * 1000),
#{state.private_field} = $2
WHERE #{state.key_field} = $3"
end
@impl true
def reserve(state) do
"UPDATE #{state.table}
SET #{state.lock_field} = #{reserve_at(state)}
WHERE #{state.lock_field} BETWEEN 0 AND #{ready()} #{run_if(state)}
ORDER BY #{state.lock_field}, #{state.key_field}
LIMIT 1
RETURNING #{state.key_field}, #{state.private_field}"
end
defp run_if(%State{run_if: nil}), do: nil
defp run_if(%State{run_if: run_if}), do: "AND (#{run_if})"
@impl true
def cancel(state) do
"UPDATE #{state.table}
SET #{state.lock_field} = NULL
WHERE
id = $1
RETURNING #{state.lock_field}"
end
@impl true
def status(state) do
"SELECT COUNT(IF(#{state.lock_field} IS NOT NULL, 1, NULL)) AS count,
COUNT(IF(#{state.lock_field} = #{EctoSource.abandoned()}, 1, NULL)) AS abandoned,
COUNT(IF(
0 <= #{state.lock_field} AND #{state.lock_field} <= #{ready()},
1, NULL)) AS ready,
COUNT(IF(
#{ready()} < #{state.lock_field} AND #{state.lock_field} < #{stale_at()},
1, NULL)) AS delayed,
COUNT(IF(
#{stale_at()} < #{state.lock_field} AND #{state.lock_field} < #{now()},
1, NULL)) AS stale,
COUNT(IF(
#{now()} < #{state.lock_field} AND #{state.lock_field} <= #{reserve_at(state)},
1, NULL)) AS in_progress
FROM #{state.table}"
end
@impl true
def filter(state, :abandoned) do
"SELECT id FROM #{state.table} WHERE #{state.lock_field} = #{EctoSource.abandoned()}"
end
@impl true
def reset_stale(state) do
"UPDATE #{state.table}
SET #{state.lock_field} = DEFAULT,
#{state.private_field} = DEFAULT
WHERE
#{stale_at()} < #{state.lock_field}
AND
#{state.lock_field} < #{now()}"
end
defp reserve_at(state) do
"#{now()} + #{state.stale_timeout}"
end
defp stale_at do
"(NOW() - INTERVAL '5 year')"
|> time_in_msecs
end
defp msecs_ago(msecs) do
"#{now()} - #{msecs}"
end
defp now do
time_in_msecs("NOW()")
end
defp time_in_msecs(time) do
"(EXTRACT('millisecond', (#{time})) + CAST((#{time}) AS INT) * 1000)"
end
end
end