Search code examples
elixirphoenix-frameworkagent

Sharing state between processes using agents in Elixir Phoenix


I have one HTTP endpoint which creates a map and stores it using Agent.

I want to access this map when I hit another endpoint. but when I a trying to get the data from Agent it is returning empty.

Can someone please confirm if this is a valid scenario for using Agents ? If yes, What am I missing ?

Code :

defmodule BoardState do
  use Agent

  def start_link do
    Agent.start_link(fn -> %{} end, name: __MODULE__)
  end

  def add(game_id, board) do
    Agent.update(__MODULE__, fn state ->
      Map.put(state, game_id, board)
    end)
  end

  def reset do
    Agent.update(__MODULE__, fn _state -> %{} end)
  end

  def get(game_id) do
    Agent.get(__MODULE__, fn state ->
      Map.get(state, game_id)
    end)
  end

  def getKeys() do
    Agent.get(__MODULE__, fn state ->
      Map.keys(state)
    end)
  end

  def name() do
    Agent.agent()
  end
end

Code from where agent is started

`defmodule TicTacToe.Application do
  use Application

  def start(_type, _args) do
    children = [
      TicTacToeWeb.Endpoint
    ]

    **BoardState.start_link()**

    opts = [strategy: :one_for_one, name: TicTacToe.Supervisor]
    Supervisor.start_link(children, opts)
  end

  def config_change(changed, _new, removed) do
    TicTacToeWeb.Endpoint.config_change(changed, removed)
    :ok
  end
end 

I have also tried this with Genserver, but when I hit 2nd enpoint I am not able to get data stored in 1st endpoint


Solution

  • I tested your code from this repo https://github.com/sayali-kotkar/tic_tac_toe on Elixir 1.9. Your code looks acceptable. This is working for me or I'm misinterpreting the problem.

    1st request:

    curl -X POST localhost:4000/game
    

    1st response:

    {
       "board":{
          "Cell(1, 1)":"empty",
          "Cell(2, 1)":"empty",
          "Cell(3, 1)":"empty",
          "Cell(1, 2)":"empty",
          "Cell(2, 2)":"empty",
          "Cell(3, 2)":"empty",
          "Cell(1, 3)":"empty",
          "Cell(2, 3)":"empty",
          "Cell(3, 3)":"empty"
       },
       "game_id":67,
       "status":"success"
    }
    

    2nd request:

    curl -X PUT localhost:4000/game/67 \
    --header "Content-Type:application/json" \
    --data '{"player_id":0, "row": 1, "column": 2}'
    

    2nd response:

    {
       "board":{
          "Cell(1, 1)":"empty",
          "Cell(2, 1)":"empty",
          "Cell(3, 1)":"empty",
          "Cell(1, 2)":0,
          "Cell(2, 2)":"empty",
          "Cell(3, 2)":"empty",
          "Cell(1, 3)":"empty",
          "Cell(2, 3)":"empty",
          "Cell(3, 3)":"empty"
       },
       "game_id":67,
       "status":"success"
    }