Aguxez

Aguxez

I’m building a bot for a server just for fun and get a test of elixir more ‘in-depth’, the bot has to save state so I’m using Agents, everything is kinda working as intended for now. I’d like that the bot “creates” a new game room if it is in another server, so, it should spawn another process and save the new state to that pid, right? That’s what I understood about processes until now, how can I spawn a new process if a given command is executed? For example

>>start (Which is a command from the server to trigger the start_link() function)

Bot spawns a new process with an empty state but if I execute the >>start command again I get an error saying that the process is already running (I will save the id of the server so no more than one process is spawned for server), obviously not spawning a new process, so that’s my doubt, how can I spawn new processes with an empty state? Is that the way it should be done? Every process spawned has it’s own state and do not interfere with another one?

I’m using the module name as the name for the process, maybe that’s why the >>start command is always referenced to the same process? Sorry if I was not too clear with my issue, please tell me and I’ll elaborate.

Showing Posts 1 to 10

OvermindDL1

OvermindDL1

Eyup, don’t name your process, hold the pid instead. :slight_smile:

And yes, every process’s state/stack is distinct. :slight_smile:

Aguxez

Aguxez OP

Alright, that problem is solved then, after holding the pid in a variable I need to access it from other blocks in the same module, the commands are in a case, since the >>start command starts the link with the Agent I can’t access the variable outside of that block, which can be the most efficient way of getting that pid? Thanks for the help.

OvermindDL1

OvermindDL1

Well I certainly would not use an Agent, but to pass it out of a block you just return it from that block, what issue were you having with that?

Aguxez

Aguxez OP

Ah, sorry, not a block, it was a clause, as far as I know you can’t return values from case clauses, right?

I have something like this:

case msg.content do
  @prefix <> "start" ->
    # Main server
    {:ok, pid} = Cass.Server.start_link(
      %{name: msg.author.username, id: msg.author.id}
    )

  @prefix <> "queue" ->
    # here I need to get the pid to know it's state
end

Or what would you recommend me to do in this situation?

net

net

Also, the result of the last expression in a case clause gets returned:

value =
  case true do
    true -> 1
    false -> 0
  end

value # 0
OvermindDL1

OvermindDL1

*Everything* returns something, and your @prefix <> "start" -> is returning {:ok, pid}, just assign the output of the case msg.content do to a variable and pass it around in whatever you are holding state in. ^.^

This would work for a single node, but not multi-node, so it depends on your use case.

Aguxez

Aguxez OP

Ah, I didn’t know that, thanks both for your input! :sweat_smile:

Aguxez

Aguxez OP

Argh, sorry but I think that I should explain my issue a little better and give more context, I’m using a library for Discord and the way that you listen for events is through a handle_event function and then you match the contents of the message with, well, what you’re expecting, this is part of my code:

def handle_event({:MESSAGE_CREATE, {msg}, _ws_state}, state) do
    case msg.content do
      @prefix <> "start" ->
        {:ok, pid} = Cass.Server.start_link(
          %{name: msg.author.username, id: msg.author.id}
        )
        pid # at first glance what I understood was this and that'd be it if I wanted to just return something out of this whole "case", right?
      @prefix <> "queue" ->
        Setup.get_agent(pid) # use the pid returned above as a parameter here?
    end
end

I’m getting errors saying that the pid variable doesn’t exist because of the scope, right? I mean, even if the process is running I can’t use that pid. I tried using the content of the variable as the return statement of the case, something like:

pid =
  case msg.content do
    @prefix <> "start" ->
      Cass.Server.start_link(
        %{name: msg.author.username, id: msg.author.id}
      )
    _ ->
      :ignore
  end

But, uh, I can’t use two case statements, so… I really don’t know how to initialize the process and pass the variable to get the state later on :frowning:

I need to explicitly initialize the process when the >>start command is specified because then how can I spawn the process? I tried moving the start_link function above the case but that’d match every time a message is sent and that’s a total mess, if I just wanted to use the bot on a single server it would be done already. I thought I had it but I’m still confused… well, not confused because I understand the process, I just don’t know how to implement it… :sweat:

OvermindDL1

OvermindDL1

Yeah you are not storing the pid anywhere here at all. ^.^

Assuming your state is a map, then you can do this:

def handle_event({:MESSAGE_CREATE, {msg}, _ws_state}, state) do
    case msg.content do
      @prefix <> "start" ->
        {:ok, pid} = Cass.Server.start_link(
          %{name: msg.author.username, id: msg.author.id}
        )
        %{state | pid: pid} # You return your updated state from this function, so you do that here
      @prefix <> "queue" ->
        Setup.get_agent(state.pid)
        state # Not changing the state so just passing it right back out
    end
end

So yeah, you were not actually storing the pid anywhere. ^.^

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews