Elixir phoenix debugging leads to interactive shell instead of pry - debugging

I've been trying to debug a phoenix application.
To do so I used the following instructions:
- To set a break point: require IEx; IEx.pry
- To start a debugging server: iex -S mix phx.server
The problem comes when starting the server, the above instruction leads me to the elixir interactive shell (iex(1)>) and does not allow the server to run, from here if I execute the code manually it stops in the prys but I was hopping to have the server running and stop whenever a request hit the pry. Is there any solution?
I am currently using earlang 1.20, elixir 1.5 and phoenix 1.3

It is common behavior that the iex -S mix phx.server command opens an IEx shell. It runs the web server on the port configured for the Phoenix endpoint within the respective MIX_ENV simultaneously to that. For each IEx.pry() breakpoint it executes, it should prompt on the command line whether you want to open an IEx shell there.
Check which MIX_ENV your server is running in, e.g. by typing the following in the IEx shell:
Mix.env
And then find the configuration in the files within the config/ directory. The line should look like this:
config :nameofyourapp, Web.Endpoint,
http: [port: 4000],
Maybe something other than 4000 is configured there? Or maybe some other application, or even a previously started instance of your web application already listens on that port and therefore prohibits the debug server from binding on that port? In that case, shutdown other running mix phx.server processes.

Related

AdonisJs 4.1: how to create a start script that migrates the db and start the server?

I have a dockerized AdonisJs App that I'm trying to deploy on ECS (AWS). I managed to deploy the image but now I don't know how to run migrations when I deploy.
By following a Udemy course I saw that somebody had to do the same stuff, but with laravel. In the Dockerfile instead of running CMD ['artisan','serve'] he created a start.sh script where he starts the app, put it in the background, runs the migrations, and then put the app back in the background. Here is the script:
#!/bin/sh
# turn on bash's job control
set -m
# Start the primary process and put it in the background
php-fpm &
# Start the helper process
php artisan migrate
# now we bring the primary process back into the foreground
# and leave it there
fg %1
I tried to do the same thing with Adonis, this is my script (one of many versions):
#!/bin/sh
# turn on bash's job control
set -m
# Start the primary process and put it in the background
adonis serve &
# Start the helper process
adonis migration:run
# now we bring the primary process back into the foreground
# and leave it there
fg %1
But I always get errors. For example:
The server starts but then the migrations do not run because adonis cannot connect to the database. I don't know how to debug it, since if I just start the app normally Adonis can perfectly connect to the database.
(I tried this only locally) The server starts, the migrations run but then the server process doesn't come in foreground so the application is not really started (curl localhost it gives me curl: (7) Failed to connect to localhost port 80: Connection refused) and I cannot either stop the server with ctrl+c, I have to find the docker container and stop the container.
This is what the console shows me:
SERVER STARTED
info: serving app on http://0.0.0.0:80
Nothing to migrate
Could you please help me create a script that does this?
EDIT1: I noticed that even if I create a script with only "adonis serve" it still doesn't work, so maybe that it's just not the right way to start the server trough a script?
The first problem I needed to solve was the migration command that wasn't terminating. The cause was how I was starting the adonis-scheduler package. I was starting it from the start/kernel.js file. Now instead I created a scheduler.js (inside start) with:
'use strict'
/*
|--------------------------------------------------------------------------
| Run Scheduler
|--------------------------------------------------------------------------
|
| Run the scheduler on boot of the web sever.
|
*/
const Scheduler = use('Adonis/Addons/Scheduler')
Scheduler.run()
And added this in server.js:
new Ignitor(require('#adonisjs/fold'))
.appRoot(__dirname)
.preLoad('start/scheduler') //code added
.fireHttpServer()
.catch(console.error)
By doing this my migration always terminates.
The second problem I faced was that "#!/bin/bash" wasn't supported, so I needed to change the script in a "#!/bin/sh" format. Unfortunately this format doesn't support putting job in background and move them in foreground later, so I just run the migrations and then start the server. This is the file:
#!/bin/sh
# Start the helper process
adonis key:generate
adonis migration:run --force
# Start the primary process
adonis serve

How can you run an iex session and a phoenix server attached to the same database and mix environment in production?

When you run a server like MIX_ENV=prod mix phx.server and then on another screen attached to the same server try to run a mix-environment attached iex session like iex -S mix then you get an error and shutdown with a complaint like Failed to start Ranch listener VukWeb.Endpoint.HTTP in :ranch_tcp:listen([port: 4000]) for reason :eaddrinuse (address already in use)
Is there a way to run an iex session while a server is running in a separate screen attached to the same database? I'm confused as to why iex -S mix is even trying to connect to an external port, as that iex session should have no server running nor require an external port simply for loading the mix environment?
I'm aware you can run the server with an iex session like MIX_ENV=prod iex -S mix phx.server, but my understanding is that is neither ideal for performance nor is it nice to have your iex session interrupted by streams of user logs as requests are processed (which is what we're doing right now). I also tried switching up the port like MIX_ENV=prod PORT=4040 iex -S mix but the flag seems to go ignored, as the complaint comes back the same with a reference to port 4000. I'm wonder if maybe there's some hardcoding that's causing the environment variable to be ignored, and if just undoing this hardcoding and switching it to a different port like this is the right approach, even if the port goes unused by the non-server mix environment.
If anyone has a tip on how you can get both a iex session and serving running—or has a different suggestion for workflow that makes such a desire unnecessary—would love to hear!
Thanks
Mix has a perfect very detailed documentation.
Mix.Tasks.Run is a default task. iex -S -mix is essentially equivalent to iex -S mix run.
The latter starts your application, which [wild reasonable guess] in turn starts cowboy as a dependency. Hence the error.
iex -S mix run --no-start
is what you are looking for. This task accepts several arguments, other are listed on the help page I linked.

Create Elixir Connection Bash Script

I am using one connection library to connect my Elixir shell to ActiveMQ and subscribing to the queues like below and is working well
iex --erl "-pa ebin -env DYLD_LIBRARY_PATH ./priv -env LD_LIBRARY_PATH ./priv -s qpidpn start"
:qpidpn.subscribe('amqp://127.0.0.1/queue://test')
Can someone suggest me, how to create new Elixir Mix application [i mean new module in application: bash script but not from shell] which will do that same thing. That means.
Start of qpidpn first.
Queue subscription to echo messages coming in queue.
Probably the best way would be to use a release for this. Take a look at exrm. Basically, you build the release with mix release, then run your app using rel/qpidpn/bin/qpidpn start. You can then connect to the node using iex with rel/qpidpn/bin/qpidpn remote_console, and queue a subscription with :qpidpn.subscribe('amqp://127.0.0.1/queue://test'). You can then quit the remote shell session, and your app will continue running indefinitely in the background.

Debug meteorjs application with node-inspector

I am trying to debug a meteor application at server side.
I created an environment variable export NODE_OPTIONS='--debug'.
I run meteor (version 0.7.0.1) command. It tells the debugger listening on port 5858.
I start node-inspector (version v0.7.0-2) and point to 127.0.0.1:8080/debug?port=5858, but I can see only a couple of strings, Source, Console and a prompt > where I cannot write anything.
I have this error in the console:
“The connection to ws//127.0.0.1:8080/socket.io/1/websocket/Za… was interrupted while the page was loading”.
The same if I use 0.0.0.0:8080: I can see something more of the debugger on the right panel, as Watch expression, Call stack, but the Source list is still empty.
Node-inspector should be listening, because if I stop meteor says that the remote debugging has been terminated. I cannot figure out what I am doing wrong.
have a look at https://groups.google.com/forum/#!topic/meteor-talk/EG8pe7pF3f8
Just want to share some of my experience on using node-inspector to
debug server side codes:
1. When you run Meteor, it will spawn two processes on Linux machine
(Note: I have not checked this on Windows or Mac machine)
process1: /usr/lib/meteor/bin/node /usr/lib/meteor/app/meteor/
meteor.js
process2: /usr/lib/meteor/bin/node /home/paul/codes/bbtest_code/
bbtest02/.meteor/local/build/main.js --keepalive
You need to send kill -s USR1 on process2
Run node-inspector and you can see your server code
On my first try, I modify the last line on meteor startup script in /
usr/lib/meteor/bin/meteor to
exec "$DEV_BUNDLE/bin/node" $NODE_DEBUG "$METEOR" "$#"
and run NODE_DEBUG=--debug meteor on command prompt. This only put --
debug flag on process1 so I only see meteor files on node-inspector
and could not find my code.
Any suggestion on how to modify the script so we can use "--debug"
flag on the meteor script?
Cheers,
Paul

Meteor: Debug on server side

Does anyone know a good method to debug server side code?
I tried enable Node.js debug then use node-inspector but it does not show any of my code.
I end up using console.log but this is very inefficient.
Update: I found the following procedure works on my Linux machine:
When you run Meteor, it will spawn two processes
process1: /usr/lib/meteor/bin/node /usr/lib/meteor/app/meteor/meteor.js
process2: /usr/lib/meteor/bin/node /home/paul/codes/bbtest_code/bbtest02/.meteor/local/build/main.js --keepalive
You need to send kill -s USR1 on process2
Run node-inspector and you can see your server code
On my first try, I modify the last line on meteor startup script in /usr/lib/meteor/bin/meteor to
exec "$DEV_BUNDLE/bin/node" $NODE_DEBUG "$METEOR" "$#"
and run NODE_DEBUG=--debug meteor on command prompt. This only put --debug flag on process1 so I only see meteor files on node-inspector and could not find my code.
Can someone check this on Windows and Mac machine?
In Meteor 0.5.4 this has become a lot easier:
First run the following commands from the terminal:
npm install -g node-inspector
node-inspector &
export NODE_OPTIONS='--debug-brk'
meteor
And then open http://localhost:8080 in your browser to view the node-inspector console.
Update
Since Meteor 1.0 you can just type
meteor debug
which is essentially a shortcut for the above commands, and then launch node inspector in your browser as mentioned.
Update
In Meteor 1.0.2 a console or shell has been added. It may come in handy to output variables and run commands on the server:
meteor shell
Meteor apps are Node.js apps. When running a Meteor app with the meteor [run] command, you can configure the NODE_OPTIONS environment variable to start node in debug mode.
Examples of NODE_OPTIONS environment variable values:
--debug
--debug=47977 - specify a port
--debug-brk - break on the first statement
--debug-brk=5858 - specify a port and break on the first statement
If you export NODE_OPTIONS=--debug, all meteor command run from the same shell will inherit the environment variable. Alternatively, you can enable debugging just for one run, with NODE_OPTIONS="--debug=47977" meteor.
To debug, run node-inspector in a different shell, then go to http://localhost:8080/debug?port=<the port you specified in NODE_OPTIONS>, regardless of what node-inspector tells you to run.
To start node.js in debug mode, I did it this way:
open /usr/lib/meteor/app/meteor/run.js
before
nodeOptions.push(path.join(options.bundlePath, 'main.js'));
add
nodeOptions.push('--debug');
Here are additional practical steps for your to attach debugger eclipse:
use '--debug-brk' instead of '--debug' here, because it's easier for me to attach node.js using eclipse as debugger.
add 'debugger;' in the code where you want to debug.(I prefer this way personally)
run meteor in console
attach to node.js in eclipse(V8 tools, attach to localhost:5858)
run, wait for debugger to be hit
when you start meteor in your meteor app folder, you'll see that "debugger listening on port 5858" in console.
On Meteor 1.0.3.1 (update to Sergey.Simonchik answer)
Start your server with meteor run --debug-port=<port-number>
Point browser to http://localhost:6222/debug?port=<port-number>
Where <port-number> is a port you specify.
In your code add a debugger; where you want to set your break point.
Depending on where debugger; is invoked, it will either break on your client or server browser window with inspector opened.
I like to set breakpoints via a GUI. This way I don't have to remember to remove any debugging code from my app.
This is how I managed to do it server side for my local meteor app:
meteor debug
start your app this way.
Open Chrome to the address it gives you. You MAY need to install https://github.com/node-inspector/node-inspector (it might come bundled with Meteor now? not sure)
You'll see some weird internal meteor code (not the app code you wrote). Press play to run the code. This code simply starts up your server to listen for connections.
Only after you press play you'll see a new directory in your debugger folder structure called "app". In there are your meteor project files. Set a breakpoint in there one the line you want.
Open the local address of your app. This will run your server side code and you you should be able to hit your breakpoint!
Note: you have to reopen the inspector and go through this process again each time your app restarts!
As of Meteor 1.0.2 probably the best way for server-side debugging is directly via the new built-in shell: with running server run meteor shell. More info here: https://www.meteor.com/blog/2014/12/19/meteor-102-meteor-shell
I am not sure why it was not working for you.
I am able to use it by following steps on console (Mac).
$ ps
$ kill -s USR1 *meteor_node_process_id*
$ node-inspector &
Above steps are mentioned on https://github.com/dannycoates/node-inspector. It is for attaching node-inspector to running node process.
I wrote a small meteor package called meteor-inspector which simplifies the use of node-inspector to debug meteor apps. It internally manages the lifecycle of node-inspector and hence, the user does not need to restart the debugger manually after some files have changed.
For more details and concrete usage instructions take a look at https://github.com/broth-eu/meteor-inspector.
for meteor 1.3.5.2, run
meteor debug --debug-port 5858+n
n is a non-zero number, this will cause node-inspector use 8080+n as web port.
WebStorm, the powerful IDE free for open source developers, makes it much easier to debug server-side.
I've tested it on Windows, and the configuration was painless - see my answer.
A inspector that solve my issues is meteor server console. Here is the process I followed to install it:
In your project folder, add the smart package server-eval:
mrt add server-eval
For Meteor 1.0:
meteor add gandev:server-eval
Restart meteor.
Download crx Chrome extension file from here.
Open extensions page in Chrome and drag crx file to extensions page.
Restart Chrome.
Check the web inspector out to eval server side code:
In comparison with node-inspector, I have a clearer output.
If you prefer to use nodeJS' official debugger you can call NODE_OPTIONS='--debug' meteor and then (on a different shell) node debug localhost:5858.

Resources