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

Lobbying with Elixir: Real-Time LiveView & OTP

Evadne Wu
October 11, 2019

Lobbying with Elixir: Real-Time LiveView & OTP

Learn how LiveView can supercharge your new service idea, with an example project which maintains game lobbies.

In this talk, you will learn from a constructed example how LiveView can supercharge your new service idea, with an example project which maintains online game lobbies. Follow us on a journey of Phoenix, LiveView and OTP. Walk away with weeks of your life now freed up for doing new things.

The expressive power of Phoenix LiveView has now been widely acknowledged by the community, with various teams adopting it within projects. This talk aims to provide an end-to-end view as to how it can supercharge your development process, by first constructing the design of a full-stack service with OTP, and then comparing various User Interface implementation strategies, inclusive of LiveView, Channels + Vue.js, and hand-crafted HTML/JS, among other approaches.

I will also cover various implementation strategies for integrating stateful backend services with front-end layers, which will make evident why the combination of LiveView and OTP primitives could provide you best bang for the buck.

Evadne Wu

October 11, 2019
Tweet

More Decks by Evadne Wu

Other Decks in Technology

Transcript

  1. Lobbying with Elixir:
    Real-Time LiveView & OTP
    Evadne Wu
    Head of Exam Systems, Faria Education Group
    [email protected]
    twitter.com/evadne
    revised

    11 October 2019

    View Slide

  2. Myself
    I’m here to explain why you should use Elixir.
    Inquiries: [email protected]
    Arguments: twitter.com/evadne

    View Slide

  3. 1
    Stating the Case

    View Slide

  4. Problem: Lobby Management
    Lobbies are waiting areas for prospective gamers
    Lobbies have teams and slots
    Lobbies can change state
    Users can join lobbies as players or spectators

    View Slide

  5. Lobby: Initial State
    Team 1 Role Type Team 2
    Empty Slot Scout 1 Empty Slot
    Empty Slot Scout 2 Empty Slot
    Empty Slot Soldier 1 Empty Slot
    Empty Slot Soldier 2 Empty Slot
    Empty Slot Demo Empty Slot
    Empty Slot Medic Empty Slot

    View Slide

  6. Lobby: Slot Acquisition
    Team 1 Role Type Team 2
    Player 1 Scout 1 Player 1
    Empty Slot Scout 2 Player 2
    Player 3 Soldier 1 Empty Slot
    Player 4 Soldier 2 Empty Slot
    Empty Slot Demo Player 5
    Player 6 Medic Player 6
    Users acquire
    Slots

    View Slide

  7. Lobby: Launched when Full
    Team 1 Role Type Team 2
    Player 1 Scout 1 Player 1
    Player 2 Scout 2 Player 2
    Player 3 Soldier 1 Player 3
    Player 4 Soldier 2 Player 4
    Player 5 Demo Player 5
    Player 6 Medic Player 6

    View Slide

  8. Lobby: Launched when Full
    Team 1 Role Type Team 2
    Player 1 Scout 1 Player 1
    Player 2 Scout 2 Player 2
    Player 3 Soldier 1 Player 3
    Player 4 Soldier 2 Player 4
    Player 5 Demo Player 5
    Player 6 Medic Player 6
    Let the game begin

    View Slide

  9. Problem: Solution Scope
    Build a system to organise Lobbies
    ➤ Focus on Slot Acquisition / State Propagation
    ➤ Allow users to join as Players or Spectators
    ➤ Propagate changes to all open tabs

    View Slide

  10. 2
    Keeping State

    View Slide

  11. State: The Programmer’s Burden
    In the distant past, pages were stateless. HTML Forms
    were all we needed. Nothing required JavaScript.
    We have now left this world behind and look back with
    rose-tinted glasses.

    View Slide

  12. View Slide

  13. View Slide

  14. State: The Programmer’s Burden
    We have entered a new world where the Browser has
    become an inner-platform, and each Web Application a
    distributed system of its own.
    Their components pass messages between each other
    to reconstruct and represent state.

    View Slide

  15. View Slide

  16. View Slide

  17. High-Level Structure
    Service
    UI
    Slot Request
    Slot Update

    View Slide

  18. Conventional Topology
    Server
    Database
    Load
    Balancer
    Server
    Server
    Server
    State

    Stored Here

    View Slide

  19. Conventional Topology
    Server
    Load
    Balancer
    Server
    Server
    Server
    State

    Stored Here
    Database

    View Slide

  20. Conventional Topology
    Server
    Database
    Load
    Balancer
    Server
    Server
    Server
    User 1
    User 2
    User 3

    View Slide

  21. Conventional Topology
    Server
    Database
    Load
    Balancer
    Server
    Server
    Server
    User 1
    User 2
    User 3

    View Slide

  22. Conventional Solution
    Serialise access somehow (maybe with transactions)
    Ask the data store to notify server of changes
    Subscribe for changes in a different process
    Spray changes to all matching clients

    View Slide

  23. View Slide

  24. Example: Propagation with PostgreSQL
    CREATE FUNCTION lobby_notify() RETURNS trigger AS $$
    BEGIN
    PERFORM pg_notify('lobby' || NEW.id,
    row_to_json(NEW)::text);
    RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;

    View Slide

  25. Example: Propagation with PostgreSQL
    CREATE TRIGGER notify
    AFTER UPDATE ON lobbies
    FOR EACH ROW
    EXECUTE PROCEDURE lobby_notify();

    View Slide

  26. Example: Propagation with PostgreSQL
    UPDATE lobbies
    SET players->'blu'->'scout' = …
    WHERE id = …
    AND players->'blu'->'scout' IS NULL

    View Slide

  27. View Slide

  28. Example: Propagation with Redis
    PSUBSCRIBE lobbies:/*

    SET lobbies://


    PUBLISH lobbies://


    View Slide

  29. Conventional Pain Points
    Lack of mechanism to manage cross-node messaging
    Lack of proper mechanism to manage state
    Data Store becomes the bottleneck
    Serialisation/deserialisation at boundaries can be buggy
    Proliferation of technologies

    View Slide

  30. 3
    Wrangling State

    View Slide

  31. Single Source of Truth
    Server
    Load
    Balancer
    Server
    Server
    Server
    State

    Stored Here
    Database

    View Slide

  32. Multiple Tiers of Truth
    Server
    Load
    Balancer
    Server
    Server
    Server
    State

    Stored Here
    Database
    Here Too

    View Slide

  33. Use Elixir For This
    ➤ Clustering: Built-in / Easy (Distributed Erlang / libCluster)
    ➤ Spreading Out: Easy (Swarm / Horde)
    ➤ Data Synchronisation: Built-in / Easy (ETS / Mnesia)
    ➤ Communication with JS: Easy (with Phoenix Channels)
    ➤ Communication without JS: Easy (with Phoenix Live View)

    View Slide

  34. Use Elixir For This
    Lobby

    Supervisor
    Lobby

    Server
    Lobby

    Server
    Lobby

    Server Data Store
    Lobby Channel
    Lobby Channel
    Lobby Channel
    Lobby Channel
    Lobby Channel

    View Slide

  35. Photo by Little Visuals from Pexels
    Demo

    View Slide

  36. Summary
    ➤ Backend Solution: Cookie-Cutter (OTP Style)
    ➤ Front-End Solution 1: Phoenix Channels & Presence
    ➤ Front-End Solution 2: Phoenix LiveView

    View Slide

  37. Summary: Lobby Lifecycle
    ➤ Lobby is created and held in Data Store.
    ➤ When the Lobby Page is loaded, a Lobby Channel is spawned.
    ➤ The Lobby Channel looks for its corresponding Lobby Server,
    which is returned or spawned accordingly.
    ➤ The Lobby Channel and Lobby Server are, subsequently, in
    two-way communication.

    View Slide

  38. *
    Closing the Gap

    View Slide

  39. Use Elixir!
    Do fancy things

    in half the time.

    View Slide