BitGonzo

BitGonzo

I’m trying to setup a worker for my application, so I’ve setup a simple application separately.

I’m using Verk, and from their docs:

defmodule Example.App do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec
    tree = [supervisor(Verk.Supervisor, [])]
    opts = [name: Simple.Sup, strategy: :one_for_one]
    Supervisor.start_link(tree, opts)
  end
end

However, when I hit mix run, it compiles and runs the application, and yet immediately exits. I would expect it to stay up as the supervisors run. I suspect I am missing something else which will keep the application running/waiting.

Similar to this:

Except I’m not using distillery yet - just want mix run to fire up my app in dev and have that app waiting.

Would appreciate some pointers. I know this is basic stuff, so play nice please.

I have recently found the --no-halt flag - but shouldn’t this logic be inside my application?

Showing Posts 1 to 10

idi527

idi527

Can you post mix.exs for this app?

BitGonzo

BitGonzo OP

Pretty standard, really:

defmodule MyApp.Mixfile do
  use Mix.Project

  def project do
    [
      app: :myapp,
      version: "0.0.1",
      elixir: "~> 1.4",
      start_permanent: Mix.env == :prod,
      deps: deps()
    ]
  end

  def application do
    [
      mod: {Example.App, []},
      extra_applications: [:logger]
    ]
  end

  defp deps do
    [
      {:verk, "~> 1.0"},
      {:distillery, "~> 1.5", runtime: false}
    ]
  end
end

mix run without --no-halt:

[info] Schedule Manager started
[info] Queue Manager started for queue default
[info] Workers Manager started for queue default (running)
[info] Added 0 jobs.
[info] No more jobs to be added to the queue default from inprogress list.
[info] Queue Manager started for queue priority
[info] Workers Manager started for queue priority (running)
[info] Added 0 jobs.
[info] No more jobs to be added to the queue priority from inprogress list.

..then exits immediately. As if I am running it as a script.

As I say, I think I am missing some fundamental concept behind how applications work.

peerreynders

peerreynders

See this for a starting point. If my understanding is correct mix essentially starts the processes in it’s own OS process and after it finishes the starting script it exits - taking the BEAM with it. In a development environment you are meant to use iex -s mix to run the application (vs. running a script).

BitGonzo

BitGonzo OP

Thanks. I did find that before, and was a little confused with:

def start(_type, _args) do
  IO.puts "starting"
  Task.start(fn -> :timer.sleep(1000); IO.puts("done sleeping") end)
end

In this case we are starting a simple process in our callback that just sleeps for one second and then outputs something - this is enough to satisfy the API of the start callback but we don’t see “done sleeping”. The reason for this is that by default mix run will exit once that callback has finished executing. In order for that not to happen you need to use mix run --no-halt - in this case the VM will not be stopped.

From what I am gathering, I will be responsible for writing something which halts exit? It is the fact it is exiting by default that is throwing me off.

If I am planning to build long-running apps, what is the suggestion? Can I use mix run --no-halt in development and distillery to create a release for production?

peerreynders

peerreynders

In a production deploy the application is started in it’s own process. mix run simply runs the application startup just like any other code but then exits because it is done running the code. The process of launching the application in production is entirely different. You do not use mix in production.

BitGonzo

BitGonzo OP

I won’t be using mix in production. I’ll be using distilleryto create a release and running through bin/myapp foreground etc.

But in the case of development, how do you run long-running processes for your app? I’m currently using mix run --no-halt which is working fine for my purposes, but am now interested how others are handling this.

peerreynders

peerreynders

As I stated before - typically you would be using iex -S mix so you could observe and interact with the running application directly.

Supervisor and Application: Starting Applications (You may want to start at Introduction to Mix)

BitGonzo

BitGonzo OP

Apologies! Got carried away on the SO post.

Thanks for the clarifications. I’ll go through the getting started guides before posting more questions.

I don’t think it’s helped that I’ve taken on Phoenix at the same time.

Nicd

Nicd

Using --no-halt is standard (unless you want the shell with iex -S mix). Even Phoenix’s phx.server adds --no-halt internally: phoenix/lib/mix/tasks/phx.server.ex at v1.3.0-rc.2 · phoenixframework/phoenix · GitHub

So don’t worry about it, that’s the correct usage. In production you would use e.g. distillery as you have said.

peerreynders

peerreynders

I’m not sure that is the core issue - it probably has more to do with the “I want to do Rails/Sidekiq in Elixir/Phoenix” approach. Lots of people approach Elixir/Phoenix with a “I learn best by doing a interesting project” attitude, not allowing for the fact that their current mindset may not be ideal for working with Elixir/Phoenix. This is a theme in Cameron Price’s Micropatterns: Learning to Reach Quickly for the Right Tool - where he found out that for him personally it was necessary to do lots of little exercises before his mindset shifted sufficiently before it made sense to attempt a larger project.

Now I know nothing about either Sidekiq or Verk but from scanning Verk’s documentation I’m getting the impression that the intention is to insert Verk into your application’s supervision tree - much like Ecto is running in the supervision tree of the application that is running Phoenix - so you are also confronted headfirst with OTP.

This is where another common point of confusion comes into play:

mix new hello_world

creates a library application, while

mix new hello_world --sup

creates what you more conventionally would think of as an “application”. A library application doesn’t implement the application callbacks and as a result can’t be started or stopped. Most library applications will however still autonomously manage their own processes once they are included in the primary application’s supervision tree.

So it seems to me that Verk’s primary intent is to be run in the same primary application that is already running Ecto and the various bits that Phoenix relies on like Cowboy.

I’m used to having app and worker processes separated and scaling them separately. As such, I might have one app server on one box and 3 workers on other boxes.

Now this describes a somewhat different situation. Usually a “box” is running a node and it’s the node that is running your primary application. So each “box” runs it’s own node with applications running in it. Your description sounds like you intend to run Verk on a node that is separate from Phoenix (possibly even Ecto as part of yet another application on yet another node). This can be accomplished with distributed Elixir but interestingly:

Sorry if I came across as discouraging the use of --no-halt. To me it just seemed more advantageous to seize the opportunity to shed a bit more light of what an “application” actually is in the Elixir world rather than sweeping it under the carpet with --no-halt.

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
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
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
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
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

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
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
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
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

Latest on Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews