Arc Forumnew | comments | leaders | submitlogin
How do I run mzscheme non-interactively?
4 points by user2 3532 days ago | 17 comments
I would like to run hacker news in batch mode, without the mzscheme interaction. How could I do this?

Also a more comprehensive guide on running webapps would be nicer. E.g. how to run it alongside apache, or listening on a particular ip address? Thanks.



3 points by akkartik 3532 days ago | link

The mzscheme over commandline question came up recently: http://arclanguage.org/item?id=10772 Tell us if you get asv running over that.

Re apache: I usually run rails on its own port and use rewrite rules inside apache to shunt traffic to it. arc should be the same.

e.g. from my apache config:

  <VirtualHost *:80>
  RewriteEngine On

  ...

  RewriteRule ^/blog/(.*)$ http://akkartik.name:8080/blog/$1 [P,QSA,L]
  </VirtualHost>
Apache is a morass, debugging it is hell. You'll find the RewriteLog and RewriteLogLevel directives useful. Tell us if you get it working.

-----

2 points by thaddeus 3532 days ago | link

> I would like to run hacker news in batch mode ?

Why would you want to do that? If it's just so the terminal window isn't up, I would suggest using screen -> http://www.gnu.org/software/screen, or if using a mac you could run an apple script which would run the process silently:

     do shell script "cd /Users/thaddeus/arc;
     /Users/thaddeus/scheme422/bin/mzscheme -f loadscript.scm"
> how to run it alongside apache, or listening on a particular ip address?,

I think this is more an apache discussion point so I would suggest google searching 'mod proxy'. There's are tonnes of write ups on this kind of stuff and Linode.com has in-depth how to's. Mod Proxy just redirects incoming requests from an IP/domain to a specific port. As for Arc see the function (asv) which you can change the port number and just run it - I think it's in srv.arc.

-----

1 point by user2 3532 days ago | link

Let me describe a bit more:

Here's what I normally do as per how-to-run-news.txt

mzscheme -f as.scm

I get the mzscheme prompt. I type:

(load "news.arc") (nsv)

It runs well, so far so good, but I have the interactive interpreter. As soon as I shut down, the service disappears.

To run it as a shell script I looked at mzcheme man page and tried to run the following in a script called run_hacker_news.sh:

[script starts] #! /bin/sh #|

exec /home/bahadir/mz/bin/mzscheme -f as.scm |# (load "news.arc") (nsv) [script ends]

This doesn't work. I just want to run it and logout so it stays running. It's a linux box. Thanks a lot.

-----

1 point by thaddeus 3531 days ago | link

> It runs well, so far so good, but I have the interactive interpreter. As soon as I shut down, the service disappears.

This is where 'screen' comes in handy. Screen is a threaded model: it assigns a single thread for each 'screen' used. It also has a built in command to detach from your screen session (CNTRL+a d). After detaching you can then close the terminal window and arc will still be running as a silent thread. To get back just launch screen with the option to re-attach ($ screen -x).

-----

1 point by user2 3532 days ago | link

The parts with parenthesis () are multi-line, the post is displayed as single line somehow.

-----

1 point by thaddeus 3531 days ago | link

You need an extra line break to separate lines.

  Or indent a line by at least two spaces to get text verbatim.

-----

1 point by user2 3531 days ago | link

OK I read the document on unix commandline still no luck.

I created the following arc command script:

[script start]

#! /bin/sh ## arc: launcher for Arc. Put this file in your $PATH and chmod +x it.

ARC_DIR="/home/user/arc3/" # change this, obviously

rlwrap mzscheme -qr ${ARC_DIR}as.scm $@ # $@ holds the list of cmdline args

# notice the mzscheme switch is "-qr" and not "-f" here

[script end]

I then created the following run-hacker-news.arc:

[script start]

#!/usr/bin/env arc

(load "news.arc")

(nsv)

[script end]

I then run this by:

./run-hacker-news.arc

I get the arc prompt, but nothing about the webserver listening on 8080. What am I doing wrong?

-----

1 point by palsecam 3531 days ago | link

Did you also apply the patch? (http://arclanguage.org/item?id=10345)

Because I just tried, and something like:

  [script launch-asv.arc]
  #!/usr/bin/env arc
  (asv)
  [script end] 

  $ chmod +x launch-asv.arc && ./launch-asv.arc &
  [1] 2439
  $  # there is no "serving on 8080" message, but...
... go to http://localhost:8080/: "it's alive". So it's OK.

Anyway yes, Lisp is special, and the use of `screen' or the like may be better.

(n.b: if you don't launch the script in the background (no '&'), you see the message, and get no prompt. But you need to keep the terminal open.)

-----

1 point by user2 3531 days ago | link

No I hadn't applied the patch. I did the following:

[cmdline start]

linuxbox arc3 # patch -p1 < ../arc-unix.patch (Stripping trailing CRs from patch.) patching file ac.scm Hunk #1 succeeded at 1112 (offset -15 lines). (Stripping trailing CRs from patch.) patching file as.scm [cmdline end]

The patch did seem to apply but not perfectly.

Now I get:

[cmdline start]

linuxbox arc3 # ./run-hacker-news.arc reference to undefined identifier: empty?

[cmdline end]

which has (asv) in it just like your example script. If I call arc command script I get the same error. This is arc3.1.tar from ycombinator.com

Also what does (asv) do instead of (load "news.arc") (nsv)? I don't know lisp but will surely learn if I can get this running for starters.

How are generally other people running it detached? I didn't think it would require this many steps.

-----

1 point by palsecam 3531 days ago | link

> reference to undefined identifier: empty?

Strange, which version of mzscheme do you use (`mzscheme -v')? 'empty? is in the MzScheme base "scheme" module for me (MzScheme 4.2.1)!

Anyway, 'empty? is called only in as.scm, and you can actually leave this file unchanged for your case (I think). Just patch ac.scm.

> Also what does (asv) do instead of (load "news.arc") (nsv)?

'asv is used to start the "Appplication server" defined in "app.arc". App.arc is generic, and news.arc use/require it. I use it in the example to see if maybe it was a problem w/ news.arc specifically (and because I feel lazy about typing "(load ...)": app.arc is in the Arc "stdlib" (see the file "libs.arc"), and so is loaded by default).

'nsv is defined like this, in "news.arc":

   (def nsv ((o port 8080))
     [...]        ; do news-specific init stuff...
     (asv port))  ; relay to 'asv, which itself relays to 'serve (defined in srv.arc)
The "sv" in "asv" / "nsv" is for "serve".

> How are generally other people running it detached?

They don't: Arc is different :-D

---

Ah also, to start the news server in the background, no need of a script, you could use:

  $ echo '(nsv)' | arc news.arc - &
But assuming you use a slightly improved version of the (full) patch this time:

  in as.scm:

  -      (for-each (lambda (f) (aload f)) args)  ; ...execute them!
  +	 (for-each (lambda (f) (if (string=? f "-") (tl) (aload f))) args)
But you still need to leave the terminal opened. To fix that, I don't know you may use some Unix daemon-ization magic. It becomes specific to your needs. Are you trying to use the news.arc forum on a (distant) server?

Once again, consider `screen'. Arc has no Unix signal handling for instance, so an "Arc daemon" would not be "powerful". The only possible interaction would be to kill it (via `kill'). Better keep an eye on it, i.e: keep a REPL opened to manage your forum.

---

Have a look at http://arclanguage.org/formatdoc

-----

2 points by user2 3531 days ago | link

Thanks for the info.

I am using mzscheme 372 as described here: http://arclanguage.org/install

I tried:

  $ echo '(nsv)' | arc news.arc - &
I got repetitively:

  arc> Error: "Bad object in expression #<eof>"
  arc> Error: "Bad object in expression #<eof>"
  ...
I am using a remote vps, hence I would like to start the service and quit the server. To be honest, a web service without daemonizing does not sound very intuitive. When I say I need to stay connected to the server to keep the service alive, forums users say "Ah man, what kind of a computer engineer are you?" ;-) I think something like this must be done: http://www.itp.uzh.ch/~dpotter/howto/daemonize

Do you think if I get the latest version of mzscheme your patch it will work? What about the 15 lines offset hunk? Patch didn't seem to apply perfectly.

-----

2 points by palsecam 3531 days ago | link

Yes, try the latest version of MzScheme. Seeing "bad object in expression #<eof>", I'm not even sure ac.scm is patched correctly.

http://arclanguage.org/install has not been updated, but the big feature of the 3.1 version is that it can runs on recent (> 4.1) MzScheme. See http://arclanguage.org/item?id=10254.

Edit: oh yes, maybe you use Arc 3! The current version is Arc 3.1: see the previous link. Direct download: http://ycombinator.com/arc/arc3.1.tar. The patch is to be used with the 3.1!

> To be honest, a web service without daemonizing does not sound very intuitive. When I say I need to stay connected to the server to keep the service alive, forums users say "Ah man, what kind of a computer engineer are you?"

I agree it's not intuitive, but the use of `screen' + long-lived REPL to manage the forum can actually be seen as quite smart:

  $ screen arc
  arc> (load "news.arc")
  arc> (thread:nsv)   ; start it in a new thread, to not block the REPL
  arc> ^A d  ; CTRL-A d, to detach the `screen'
  [detached]
Your forum is started and your screen session detached. You can safely logout and exit your SSH session at this point.

At any time, you can login back to the server and do:

  $ screen -r   # resume
  arc> ; you're in front of the forum REPL
  arc> requests*  ; ultra basic analytics: show the number of requests served
  161803
  arc> (change-some-settings)  ; you get the idea
And if you need to stop the server and exit Arc:

  arc> (exit)  ; or just ^D if you have applied the patch
  [screen is terminating]
  $ 
One thing that is missing is there is no watchdog, no automatic restart in case of failure (I mean big failure, like: the Arc process died). Sure, it's not as solid as the daemontools (http://cr.yp.to/daemontools.html), but it should suffice. srv.arc has some kind of protection against flood, handler threads that would get mad, etc.

If you really want to just echo '(nsv)' | arc news.arc -, then use version 3.1, the patch and a small shell or Perl wrapper script to daemonize the Arc process. Some fork + redirect standard ports + setsid magic, then exec the Arc process.

In Perl, from `perldoc perlipc':

      use POSIX 'setsid';

      sub daemonize {
          # chdir '/'               or die "Can't chdir to /: $!";
          open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
          open STDOUT, '>/dev/null'
                                  or die "Can't write to /dev/null: $!";
          defined(my $pid = fork) or die "Can't fork: $!";
          exit if $pid;
          setsid                  or die "Can't start a new session: $!";
          open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
      }
Or play it hardcore and use the daemontools :-P!

-----

1 point by user2 3527 days ago | link

Thanks, I got it working. For reference, particularly your screen trick worked very well over ssh. -L option also helps if screen dies on you, it creates a log file in the current dir that you can check and see what went wrong.

Next, I believe I need to learn a bit of arc to see how I can make changes on the website.

-----

1 point by user2 3531 days ago | link

OK thanks, let me try these.

By the way, somehow I managed to log out and the server still seems to be up. I didn't use screen or anything. I will investigate how it worked.

-----

1 point by akkartik 3531 days ago | link

Sometimes interactive processes will 'go rogue' when you ctrl-c them. Run ps and kill to get rid of it.

-----

1 point by thaddeus 3531 days ago | link

Maybe just put:

  (load "news.arc")
  (nsv)
at the bottom of your as.scm file (since this file loads successfully).

-----

1 point by conanite 3531 days ago | link

In addition to all these excellent suggestions, you might take a look at

  start-stop-daemon
which is generally useful on linux for starting background processes. You should be able to find some examples under /etc/init.d

-----