Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Protocols and Structs

Protocols and Structs

Processing a data flow in Elixir

Claudio Ortolina

December 02, 2015
Tweet

More Decks by Claudio Ortolina

Other Decks in Programming

Transcript

  1. STRUCTS %Checkin{id: "123", lat: 51.50, lng: 0.12} struct(Checkin, id: "123",

    lat: 51.50, lng: 0.12) struct(Checkin, %{id: "123", lat: 51.50, lng: 0.12}) struct(Checkin, id: "123", lat: 51.50, lng: 0.12, ignored: true)
  2. IMPLEMENTATION defimpl Persistence, for: Checkin do def create(checkin) do %Doc{class:

    "Checkin", fields: Map.from_struct(checkin)} |> Repo.create end end
  3. FALLBACK defimpl Persistence, for: Any do def create(thing) do class

    = Map.get(thing, :__struct__) |> to_string %Doc{class: class, fields: Map.from_struct(thing)} |> Repo.create end end
  4. IDENTIFY { "meta" : { "version" : 1, "topic" :

    "checkins", "type" : "create", "request_id" : "15456d4e-782b-11e5-8bcf-feff819cdc9f" }, "data" : { "ref" : "123ASDS", "lat" : 51.50, "lng" : 0.12 } }
  5. IDENTIFY def identify(payload) do case payload["meta"] do %{"version" => 1,

    "topic" => "checkins", "type" => "create"} -> V1.Checkins.Create _other -> {:error, :unsupported_payload} end end
  6. POPULATE def populate(struct_name, payload) do request_id = get_in(payload, "meta", "request_id")

    struct_attrs = Map.put(payload["data"], "request_id", request_id) Kernel.struct(struct_name, Utils.atomise_map(struct_attrs)) end
  7. LOG defimpl String.Chars, for: V1.Checkins.Create do def to_string(create_struct) do "type=create

    status=accepted request_id=#{create_struct.request_id} ref={create_struct.ref}" end end
  8. PROCESS defimpl Job, for: V1.Checkin.Create do def process(create_struct) do {:ok,

    new_record} = Persistence.create(create_struct) %V1.Checkin.Created{request_id: create_struct.request_id, record: new_record} end end
  9. LOG defimpl String.Chars, for: V1.Checkins.Created do def to_string(created_struct) do "type=create

    status=processed request_id=#{create_struct.request_id} id={created_struct.record.id}" end end
  10. NOTIFY defimpl Notify, for: V1.Checkin.Created do def topics(created_struct), do: ["checkins",

    "users"] def to_message(created_struct) do %Message{request_id: created_struct.request_id, type: :create, data: %{id: created_struct.record.id}} end end