-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validateur NeTEx : polling des résultats #4326
Changes from 2 commits
39978f5
8bb70c9
753eb6a
dbe68c9
8980dbf
46e1a06
4f231ad
6d7ea58
822e114
69c1ce0
566d743
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
defmodule Transport.Jobs.NeTExPollerJob do | ||
@moduledoc """ | ||
Companion module to the validator for NeTEx files, used to handle long | ||
standing validations. | ||
""" | ||
use Oban.Worker, tags: ["validation"], max_attempts: 180, queue: :resource_validation | ||
|
||
alias Transport.Validators.NeTEx | ||
|
||
@impl Oban.Worker | ||
def perform(%Oban.Job{ | ||
args: %{ | ||
"validation_id" => validation_id, | ||
"resource_history_id" => resource_history_id | ||
}, | ||
attempt: attempt | ||
}) do | ||
NeTEx.poll_validation_results(validation_id, attempt) | ||
|> NeTEx.handle_validation_results(resource_history_id, fn ^validation_id -> snooze_poller(attempt) end) | ||
end | ||
|
||
def snooze_poller(attempt) do | ||
{:snooze, NeTEx.poll_interval(attempt)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. En lisant https://hexdocs.pm/oban/Oban.Worker.html#module-snoozing-jobs j'ai l'impression que C'est ce qu'on souhaite ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Damned, bien vu. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pour l'instant ma conclusion c'est que je peux pas proprement tester ce comportement... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. J'ai testé manuellement le comportement. Les helpers d'Oban n'émulent pas le snoozing. |
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
defmodule Transport.Jobs.OnDemandNeTExPollerJob do | ||
@moduledoc """ | ||
Job in charge of polling validation results from enRoute Chouette Valid. | ||
|
||
Upon success it stores the result in the database. | ||
""" | ||
use Oban.Worker, tags: ["validation"], max_attempts: 30, queue: :on_demand_validation | ||
alias Transport.Jobs.OnDemandValidationHelpers, as: Helpers | ||
alias Transport.Validators.NeTEx | ||
|
||
def later(validation_id, multivalidation_id, url) do | ||
%{validation_id: validation_id, id: multivalidation_id, permanent_url: url} | ||
|> new(schedule_in: {20, :seconds}) | ||
|> Oban.insert() | ||
|
||
Helpers.delegated_state() | ||
end | ||
|
||
def perform(%Oban.Job{args: %{"id" => multivalidation_id} = args, attempt: attempt}) do | ||
ptitfred marked this conversation as resolved.
Show resolved
Hide resolved
|
||
check_result(args, attempt) | ||
|> Helpers.handle_validation_result(multivalidation_id) | ||
end | ||
|
||
def check_result(%{"permanent_url" => url, "validation_id" => validation_id}, attempt) do | ||
case NeTEx.poll_validation(validation_id, attempt) do | ||
{:error, error_result} -> handle_error(error_result) | ||
{:ok, ok_result} -> handle_success(ok_result, url) | ||
{:pending, _validation_id} -> handle_pending(attempt) | ||
end | ||
end | ||
|
||
def handle_error(error_result) do | ||
error_result | ||
|> build_error_validation_result() | ||
|> Helpers.terminal_state() | ||
end | ||
|
||
def handle_success(ok_result, url) do | ||
ok_result | ||
|> build_successful_validation_result(url) | ||
|> Helpers.terminal_state() | ||
end | ||
|
||
def handle_pending(attempt) do | ||
attempt | ||
|> NeTEx.poll_interval() | ||
|> Helpers.snoozed_state() | ||
end | ||
|
||
defp build_successful_validation_result(%{"validations" => validation, "metadata" => metadata}, url) do | ||
%{ | ||
result: validation, | ||
metadata: metadata, | ||
data_vis: nil, | ||
validator: NeTEx.validator_name(), | ||
validated_data_name: url, | ||
max_error: NeTEx.get_max_severity_error(validation), | ||
oban_args: Helpers.completed() | ||
} | ||
end | ||
|
||
defp build_error_validation_result(%{message: msg}) do | ||
%{ | ||
oban_args: Helpers.error(msg), | ||
validator: NeTEx.validator_name() | ||
} | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
defmodule Transport.Jobs.OnDemandValidationHelpers do | ||
ptitfred marked this conversation as resolved.
Show resolved
Hide resolved
|
||
@moduledoc """ | ||
Shared code for jobs implementing the On Demand validation. | ||
""" | ||
import Ecto.Changeset | ||
import Ecto.Query | ||
alias DB.{MultiValidation, Repo} | ||
|
||
def terminal_state(result), do: {:terminal, result} | ||
def delegated_state, do: :delegated | ||
def snoozed_state(duration_in_seconds), do: {:snooze, duration_in_seconds} | ||
|
||
def completed, do: %{"state" => "completed"} | ||
|
||
def error(error_message), do: %{"state" => "error", "error_reason" => error_message} | ||
|
||
def handle_validation_result(result, multivalidation_id) do | ||
case result do | ||
{:terminal, changes} -> update_multivalidation(multivalidation_id, changes) | ||
:delegated -> :ok | ||
{:snooze, _duration_in_seconds} -> result | ||
end | ||
end | ||
|
||
defp update_multivalidation(multivalidation_id, changes) do | ||
validation = %{oban_args: oban_args} = MultiValidation |> preload(:metadata) |> Repo.get!(multivalidation_id) | ||
|
||
# update oban_args with validator output | ||
oban_args = Map.merge(oban_args, Map.get(changes, :oban_args, %{})) | ||
changes = changes |> Map.put(:oban_args, oban_args) | ||
|
||
{metadata, changes} = Map.pop(changes, :metadata) | ||
|
||
validation | ||
|> change(changes) | ||
|> put_assoc(:metadata, %{metadata: metadata}) | ||
|> Repo.update!() | ||
|
||
:ok | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Faudrait-il ajouter du
unique
pour éviter plusieurs exécutions pour une même validation/resource history ?C'est possible d'avoir ce job ajouté plusieurs fois ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je vais étudier ça.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
J'ai ajouté un
unique: [fields: [:worker, :args]]