polyglot

polyglot

Questions about a game I created (handling multiple concurrent users and is there a way to hook into the server using :observer.start?)

I have tried creating a simple application Games where a http server is running and users can interact with it and play games. I have also embedded a demo in the README to see how to play it. I have missed adding tests and error handling. I have few questions regarding it.

Questions:

  1. Is this a correct way to handle multiple concurrent users where the application accepts a client connection and spawns a new process to serve it. The user can then play a game and the server creates a new task for it and awaits for a fixed time.
game = Task.async(fn -> RockPaperScissors.play(id, client_socket) end)
Task.await(game, 1 * 60 * 1000)
  1. I have added :observer, :wx, :runtime_tools in extra_applications:. Since I am starting a http server the terminal blocks. Is there a way to hook into the server using :observer.start() or other means and see how many users are currently playing?

I would be very grateful if you could provide some feedback. Thanks.

Most Liked

RudManusachi

RudManusachi

Is this a correct way to handle multiple concurrent users where the application accepts a client connection and spawns a new process to serve it.

Absolutely! That’s the way to go! For example, in a nutshell, Phoenix Channels and LiveViews hold a process for each stateful web socket connection.

Since I am starting a http server the terminal blocks. Is there a way to hook into the server using :observer.start() or other means and see how many users are currently playing?

The simplest, in your scenario, probably would be somewhere in application.ex in start callback just call :observer.start() so once you start the app - it first would start the observer and then start the server itself (though you don’t want that by default for users, maybe via some ENV variable can be configured?)

However, some notes for the reference:

  1. as mentioned in docs:

    Escripts should be used as a mechanism to share scripts between developers and not as a deployment mechanism. For running live systems, consider using mix run or building releases. See the Application module for more information on systems life-cycles.

    So one alternative option would be if running the app with mix (either release or just mix run) we could start it as named node, for example:

    iex --sname server -S mix
    

    (here we start our mix project in a Node named “server”)
    and now from another terminal we could attach iex as a remote shell with

    iex --remsh server --sname observer
    

    (Here we start a node named “observer” and attach remsh (a remote shell) to the node “server”)

    As of now, it would require to manually start the HttpServer…

    Games.HttpServer.start(9000)
    

    so once we start the server - it will block the shell, just as with your escript. But we have another shell attached to the server! where we could run :observer.start()! or whatever we want!
    (though it would probably make sense to have that Games.HttpServer.start to be part of the main Application supervision tree… so it starts automatically and doesn’t block your shell)

  2. In your scenario I’d recommend to spawn a “supervised” process either through DynamicSupervisor or Task.Supervisor, instead of just bare bone spawn(fn -> ... end).

    We encourage developers to rely on supervised tasks as much as possible. Supervised tasks improve the visibility of how many tasks are running at a given moment and enable a variety of patterns that give you explicit control on how to handle the results, errors, and timeouts.

    Task — Elixir v1.16.0

    Plus, processes that are parts of a supervision tree are not only more flexible with tree are nicely shown in the “applications” tab in :observer :slightly_smiling_face:

Where Next?

Popular in Questions Top

stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Kagamiiiii
Student & New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
idi527
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir iex(2)...
New

Other popular topics Top

josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

We're in Beta

About us Mission Statement