Error, :ets.insert inside phoenix route

inside def start/2 in lib/app/application.ex, i put :

:ets.new(:danilla_session, [:named_table])

and somewhere in POST method, i call ets like :

:ets.insert(:danilla_session, {username, guid})
:ets.insert(:danilla_session, {guid, username})

i got Argument error

[error] #PID<0.457.0> running DanillaWeb.Endpoint (connection #PID<0.455.0>, stream id 1) terminated            
Server: localhost:4000 (http)                                                                                   
Request: POST /login                                                                                            
** (exit) an exception was raised:                                                                              
    ** (ArgumentError) argument error                                                                           
        (stdlib) :ets.insert(:danilla_session, {"admin", "guid-1d8ad278b9632ad119899hcfc482aa97"})

Your table is not public, only its owner is able to write to it, this is the :protected-mode, which is the default, there are also two further access modes:

public

Any process can read or write to the table.

protected

The owner process can read and write to the table. Other processes can only read the table. This is the default setting for the access rights.

private

Only the owner process can read or write to the table.

4 Likes

umm yeah :

:ets.new(:danilla_session, [:set, :public, :named_table])

but is there any safer way to do that without make public table ?

Pass the tid around explicitely to those that are allowed to write (while not making it named), or channel writes through a single process.

1 Like

i still don’t know about tid, public variable with same process, etc, i use :public for a while

The tid is the table id which is returned from the :ets.new/2 call. For a named table the tid is the table name but for an unnamed table it is a reference. To access a table even if it is :public you always need the tid.

4 Likes

thank you ^^, I still don’t know the elixir code structure, something like, define one-same variable, and call it across the code, umm yeah, I try to learn as fast as possible, but forget the basics :frowning:

Don’t feel bad, it’s a big switch. :slight_smile:

What’s basically said here is that you make a table without the :public and :named_table options (so basically only with [:set]) but you will have to store the result of :ets.new and pass it around (that’s the reference to the ETS table). You can use a small GenServer or Agent to store the table reference and encapsulate it in a module so you can then do MySecretTable.get_ref() for example.

2 Likes