mix ecto.drop && mix ecto.setup
iex -S mix phx.server
{:ok, user, pid} = Les.UserEntity.create(%{username: "u1", name: "n1"})
user
pid- lib/les/user_entity.ex
Les.UserEntity.get(pid)
Les.UserEntity.update(pid, %{name: "gpad"})
{:ok, user} = Les.UserEntity.get(pid)
user.name-
Show the supervisor tree in
application.ex -
Explain the EntitiesSupervisor ->
{:ok, user, pid} = Les.UserEntity.create(%{username: "kv1", name: "kv1"})
{:ok, user, pid} = Les.UserEntity.create(%{username: "kv2", name: "kv2"})
{:ok, pid1} = Les.UserEntity.find(1)
{:ok, pid2} = Les.UserEntity.find(2)
{:ok, pid3} = Les.UserEntity.find(3)Show the code of the find in user_entity.ex that is related to supervisor.
{:ok, pid1} = Les.UserEntity.find(1)
Process.alive?(pid1)
Process.exit(pid1, :exit)
Process.alive?(pid1)The entity is restarted because we sping the process under a supervisor. Change the restart model.
We can set something different (timeout).
Remember the supervisor in application.ex
Show the products (uncomment info)
Les.Products.all()
Show the code of products (add/remove provider)
Supervisor.which_children(Les.ProductsFetcherSupervisor)
Process.exit(pid("0.442.0"), :exit) Everything is lost and restarted ...
Remember the supervisor in application.ex
Show PaymentProcessorSupervisor
Now we can make a payment ...
{:ok, pid} = Les.UserEntity.find(1) Les.Products.all product = Les.Products.all |> Enum.random {:ok, cart} = Les.UserEntity.add_to_cart(pid, product.id, 1) Les.UserEntity.checkout_and_pay(pid) Les.UserEntity.invoices(pid, [])
how to execute the test
elixir --name [email protected] -S mix test
MIX_ENV=gpad_1 iex --name [email protected] -S mix run MIX_ENV=gpad_2 iex --name [email protected] -S mix run MIX_ENV=gpad_3 iex --name [email protected] -S mix run
:riak_core.join(:'[email protected]') :riak_core.join(:'[email protected]')
Les.ring_status()
{:ok, pid1} = Les.UserEntity.find(1) {:ok, pid2} = Les.UserEntity.find(2) {:ok, pid3} = Les.UserEntity.find(3)
Les.Products.all Les.UserEntity.add_to_cart(1, , 1)
Les.UserEntity.checkout_and_pay(1) Les.UserEntity.invoices(1, [])
Kill node 3 -> pay on node 2
mix ecto.drop && mix ecto.setup
iex -S mix phx.server
{:ok, user, pid} = Les.UserEntity.create(%{username: "u1", name: "n1"}) cart = user.cart Les.Products.all product = Les.Products.all |> Enum.random cart = Les.Carts.Cart |> Les.Repo.get(1) Les.
- Phoenix is not your application
- Embrace state outside in DB -> not only DB
- Sasa Juric Functionnal vs Process
Let it crash (not too much)
Articolo ADM -> Entity Activity https://queue.acm.org/detail.cfm?id=3025012
https://www.youtube.com/watch?v=MMfYXEH9KsY
Torben -> Short-lived process for small task ... Focus on protocol (MSCS)
Wait registration and do something ...
What could go wrong ...
gproc for reg & pub/sub
Timeouts, always !!!
Shoert -lived process fro samll things ..
Description: POS sistem where you can:
- Create user
- Buy some "special" thing (timeout minutes)
- Pay ...
- Report !???
So create user ... think API (URL) POST /user ... GOOD, better than think to the DB schema, or which lib use. I would think on API.
Phoenix is not our application
Open the shell and think which API I want to create the user.
Les.Accounts.create_user %{name: "gino", username: "gino"}
Les.Accounts.create_user %{name: "gino", username: "gino"} # error
Les.Accounts.create_user %{name: "gino", username: "gino1"}
Les.Accounts.create_user %{name: "gino", username: "gino#{UUID.uuid4()}"}
Les.UserEntity.create(%{name: "gino", username: "gino#{UUID.uuid4()}"})Ops I want to change the name but I need a user. I can take from previously in console but in real code or I put this logic in client or I need to reload it from server (think of a put/patch API) like
PUT /user/:id %{ name: "gino1" }
Les.Accounts.update_user user, %{name: "gino1"}
WDYT if I can move this logic inside a process ?!?
Start a process fro every users.
{:ok, pid1} = Les.UserEntity.start_link 1
{:ok, pid3} = Les.UserEntity.start_link 3
Les.EntitiesSupervisor.find_user
Les.Cart.add_product 1, 1, 1Supervisor that supervise the UserEntity. When create a new user start a new process. (Chicken-and-egg dilemma).
Nice-to-have Exit after some timeout.
The cart is something inside the user
Get the product info from ETS ...
1. Is it possible don't create the worker and use only the supervisor?
2. Can I continue to use `simple_one_for_one`
3. How Can I return fake data?
product = Les.Products.all |> hd
[cart|_] = Cart |> preload(:items) |> Les.Repo.all
{:ok, pid} = Les.UserEntity.find 36
Les.UserEntity.add_to_cart(pid, product.id, 1)-
Add some items in the carts
- Insert Item in carts
- Now we need to fix add_product
- I don't undertand the chnageset almost
-
Checkout & Pay
- Inform the Warehouse that products is reserved ...
- Fail payment -> free product
- Ok payment -> decrase qty
-
Start to think about distribution ...
-
Warehouse is to at the end ...
Warehouse -> External (another system) -> activities
Services/Router --->
Distribution --> Riak core
Postgres via docker -->