can someone pls help me to understand the baselines for Ash?
I want to be able to update a structure and do querys on a mnesia table, but i’m having trouble to understand how to do that
Contract resource
defmodule Contract do
use Ash.Resource,
data_layer: EtsTableContracts,
domain: nil, # Configuração explícita do domínio
notifiers: []
attributes do
attribute :c_identifier, :string, allow_nil?: false, primary_key?: true
attribute :status, :atom, default: :pending
attribute :reason, :map, allow_nil?: true
end
actions do
create :create do
accept [:c_identifier]
change set_attribute(:status, :processing) # Define status ao criar
end
update :update do
accept [:c_identifier, :status, :reason]
change fn changeset ->
changeset
|> Ash.Changeset.change_attribute(:c_identifier,:status, :processing)
end
end
end
end
my data_layer
defmodule EtsTableContracts do
@moduledoc """
Módulo responsável por inicializar e gerenciar o esquema e a tabela Mnesia para o estado do jogo.
"""
def init do
# Cria o esquema Mnesia (apenas se não existir)
:mnesia.create_schema([node()])
# Inicia o Mnesia
:mnesia.start()
# Cria a tabela GameState, se ainda não existir
case :mnesia.create_table(:contract, [
{:attributes, [:c_identifier, :status, :reason]},
{:type, :set},
{:ram_copies, [node()]}
]) do
{:atomic, :ok} ->
IO.puts("Tabela GameState criada com sucesso!")
{:aborted, {:already_exists, _}} ->
IO.puts("Tabela GameState já existe.")
{:error, reason} ->
IO.puts("Erro ao criar tabela GameState: #{inspect(reason)}")
end
end
end
and how does the flow of my code should be I expecto to have?
on the rubish way I was doing before trying to use Ashe, I interacted with my resouces in that way
defmodule Testespay.Genservers.ContractProcessor do
@moduledoc """
Gen server responsavel por processamento assincrono da segunda parte de verificação create_contract
a validação depende de api externa, então quando o endpoint é hitado e antes do processamento ocorrer é registrado no ets
payload == processing
o processamento é então passado pra uma task assincrona nao supervisionada (por enquanto nao supervisionada)
o estado é então atualizado pela task assim que o processamento termina
"""
@state_processing :processing
@state_approved :approved
@state_error :error
@state_error_dblimit :error_dblimit
@time_toprocessqueue 2_000
use GenServer
require Logger
def start_link(_opts) do
GenServer.start_link(__MODULE__, %{queue: :queue.new()}, name: __MODULE__)
end
def init(_) do
{:ok, %{queue: nil}} # Inicializa sem fila
end
def validate_and_registry_payload(request_map, payload) do
GenServer.cast(__MODULE__, {:validate_and_registry_payload, request_map, payload})
end
def retry_payloadqueue(payload) do
GenServer.cast(__MODULE__, {:retry_payload, payload})
end
def handle_cast({:validate_and_registry_payload, request_map, payload}, state) do
Logger.debug("payload cast post")
Logger.debug(payload)
Utils.Ets.Acess.insert_payload(payload, @state_processing, :chubby)
Task.start(fn ->
Logger.debug("executing task")
Logger.debug("payload cast post")
Logger.debug(payload)
with {:ok, payload_value} <- MyApp.Pix.PixMod.get_qrcode_value_from_payload(payload),
{:ok, resp} <- GenServerUtils.populate_utils(request_map, payload_value) do
Logger.debug("Atualizando payload no ETS para estado aprovado")
Utils.Ets.Acess.update_payload(payload, @state_approved, resp)
else
{:error, reason} ->
Logger.debug("contrato não aprovado: #{inspect(reason)}")
if reason == :max_db_limit do
GenServer.cast(__MODULE__, {:enqueue_payload, request_map})
Utils.Ets.Acess.update_payload(payload, @state_error_dblimit, :chubby)
else
Utils.Ets.Acess.update_payload(payload, @state_error, reason)
end
end
end)
{:noreply, state}
end
@impl true
def handle_cast({:enqueue_payload, valid_changeset_map}, %{queue: nil} = state) do
new_queue = [valid_changeset_map]
{:noreply, %{state | queue: new_queue}}
end
def handle_cast({:enqueue_payload, valid_changeset_map}, %{queue: queue} = state) do
new_queue = queue ++ [valid_changeset_map]
{:noreply, %{state | queue: new_queue}}
end
def handle_info(:process_queue, %{queue: queue} = state) do
MyApp.GenServer.ProcessQueue.process(queue)
Logger.warn("implementar DIREITO error handling no processamento de queue e processamento de queue")
Task.start(fn ->
process_queue_items(:queue.to_list(queue))
end)
{:noreply, %{state | queue: nil}} # Esse 'end' agora fecha a função corretamente
end
defp process_queue_items(queue_items) do
Enum.each(queue_items, fn item ->
case GenServerUtils.populate_utils_without_get_value(item) do
{:ok, _result} ->
IO.puts("Processado com sucesso: #{inspect(item)}")
{:error, reason} ->
IO.puts("Erro ao processar #{inspect(item)}: #{inspect(reason)}")
end
end)
end
end
im not into system design neither elixir, so trying to get bot at the same has being overwhelming, hope no one think it’s a lazy question