📜 ⬆️ ⬇️

Real Common Lisp website in 9 steps

Introduction





This introductory article is for those who want to try Common Lisp in web programming tasks. I will not dwell on the advantages of this language, ababo did it for me in my introductory post Developing Common Web-based Web Applications (Part One)
')
I have been working on developing web applications in Common Lisp for a little over a year and have made a large online store on Common Lisp, which I think will warn the objections of those who believe that lisp is useless for commercial use.

Today my task is to tell in details about the method of deployment of all the necessary infrastructure that I use. Using this article as a step-by-step guide, an attentive reader will be able to deploy their own website in Lisp.

Perhaps my approaches are not perfect - in this case I will be glad to constructive criticism - please do not hesitate if you do not like something - one of the goals of writing this article was to correct your own mistakes.

For those who like to squander boring installation procedures - at the end of the article there is a small delicacy that may expand your view on web programming, if you haven’t dealt with lisp before this point. Search for keywords SLIME and SWANK :)


Installing the latest version of SBCL



I use SBCL as the most convenient, common and free implementation of Common Lisp, closely intergrated with the Emacs environment, which provides convenient and comfortable work. In the repositories, as a rule, there is not the latest version of SBCL, so you can compile it from sorts or install a binary for your architecture. The latter is trivial, so in this article I will describe a compilation from source.

To compile a fresh SBCL, you can use the old one, which we will immediately install using the package manager:

$ apt-get install sbcl 


SBCL sources can be obtained here: sbcl.sourceforge.net/platform-table.html

 #  $ wget http://downloads.sourceforge.net/project/sbcl/sbcl/1.0.45/sbcl-1.0.45-source.tar.bz2 #  : $ bzip2 -cd sbcl-1.0.45.tar.bz2 | tar xvf - #      $ cd sbcl-1.0.45/ $ sh make.sh #   SBCL    $ apt-get remove sbcl #   sbcl $ sh install.sh # ,    : $ sbcl This is SBCL 1.0.45, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>. SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. * 


Congratulations, you now have a fresh version of sbcl. At the moment I am deploying it with you on my server to avoid possible inaccuracies and at the end of the article you can be sure that at least everything worked for me. Well, let's hope that it will be so :)

We put quicklisp



Two package managers, ASDF and QuickLisp, are most often used to manage libraries. The latter is much more friendly, and the first is already preinstalled with SBCL, so for now we will install QuickLisp for ourselves. On quicklisp.org all the introductory information is posted, so I will not repeat and we will go straight to the installation:

 $ wget http://beta.quicklisp.org/quicklisp.lisp $ sbcl --load quicklisp.lisp * (quicklisp-quickstart:install) * (ql:add-to-init-file) 


We put hunchentoot



Now that we have a library manager, we install
hunchentoot web server, along with all its dependencies with one command:

 * (ql:quickload 'hunchentoot) 


We put swank and slime on the server



“An even more impressive example of remote debugging occurred at NASA’s Deep Space 1 mission in 1998. Six months after the launch of the spacecraft, a small Lisp code had to fly the spacecraft for two days to conduct a series of experiments. However, the elusive race condition in the code was not revealed when testing on the ground and was discovered already in space. When the error was detected in space (100 million miles from Earth), the team was able to diagnose and correct the working code, which allowed the experiment to be completed. One programmer said the following about this:

- Debugging a $ 100 million hardware program that is 100 million miles away is an interesting experience. A spacecraft REPL provides invaluable opportunities to find and fix problems. ”


I heard about this incident long before I started to work on lisp myself, and frankly I took it as a bike that could never be repeated in our modern world of multi-megabyte executable files and equally heavy dynamic libraries. However, having become acquainted with the capabilities of remote control of the lisp-image, I was convinced that it is no more difficult than working with the code on my machine. And no incremental builds, lengthy compilation or downloads of scripts via ftp - using slime, I connect to a working system and can see and change almost everything, for example, implement hot-swappable code, or inspect any object, function or macro using powerful introspection tools.

How it works? - you ask. Inside the Lisp image on a remote server, SWANK is running - a special library that provides a backend that provides access to all the controls on a Lisp image. SWANK is written in Common Lisp and communicates with SLIME over a fairly simple text protocol.

In my Emacs-e, SLIME works in Emacs Lisp, which allows me to send commands, pieces of code, definitions of objects and structures to a remote Common Lisp image when I edit a code file. Thus, you can even not even have a copy of the source code on a remote server — in this case, no attacker can change it there, for example, to secure a backdoor.

And given the advanced tools for code generation, which distinguishes the lisp, you can have practically no code at all - let it be generated according to the data - better than a samurai who does not fight, there can only be a programmer who does not write code ... Hmm, something I here got carried away, back to the installation :)

So, if you have a remote server, like mine - you can put SWANK on it, and SLIME - on your work machine. Or
to put both that and there and there and there - the main thing then is not to confuse. Install SWANK:

 $ sbcl * (ql:quickload 'swank) 


... and SLIME

 $ wget http://common-lisp.net/project/slime/snapshots/slime-current.tgz $ tar xvzf slime-current.tgz $ cd slime-2011-01-06/ 


Carefully read the README in this directory and add to your
~ / .emacs / init.el the following code, following the correct paths

 ;; SBCL (setq inferior-lisp-program "/opt/sbcl/bin/sbcl") ; your Lisp system (setq slime-lisp-implementations '((sbcl ("sbcl")))) (setq slime-startup-animation nil) ;; SLIME (add-to-list 'load-path "~/.emacs.d/slime") ;;   slime (require 'slime) (setq slime-net-coding-system 'utf-8-unix) (slime-setup '(slime-fancy)) (setq slime-enable-evaluate-in-emacs t) 


Put the screen



Since my servers never crash (yes :) - I use screen to keep an ever-running copy of SBCL, although as far as I know, there are better practices (of which competent readers will no doubt be reminded in the comments)

If you don’t have it yet - it's time to put it:

 $ apt-get install screen 


We start sbcl in screen on the server and we start the swank-server on port 4005



 $ screen -S sbcl $ sbcl * (require 'asdf) * (asdf:oos 'asdf:load-op 'swank) * (setq swank:*use-dedicated-output-stream* nil) * (swank:create-server :coding-system "utf-8-unix" :dont-close t :port 4005) 


Connecting from Emacs-a running on your machine to a lisp image on the server



In the terminal we prokadyvaem to the host ssh-tunnel

 ssh -2 -N -f -L 4005:localhost:4005 user@host.tld 


In Emacs, connect through this tunnel.

 Mx slime-connect 127.0.0.1 4005 


Or, if your server is your home machine, you don’t need to switch anything and raise SWANK - just type in Emacs-e:

 Mx slime 


We start the hunchentoot web-server on port 4242



Now we are ready to raise the web server hunchentoot. I raise it on port 4242 and use nginx as a proxy. Also nginx gives statics and does a number of things for which it is designed as well as possible.

The nginx config for our test purposes can be very simple:

 server {
    listen 80;
    server_name localhost;
     location / {
       proxy_pass http: // localhost: 4242;
       proxy_redirect off;
    }
 }


The following code, under the authorship of archimag -a, creates a special class that allows you to immediately forward this error along with the stack-trace to a cozy emacs when an error occurs on a remote server, where you can deal with it properly. Thus, if you are connected to the server where your website is running - you will always be aware of the errors that occur at the time they appear, unlike some other languages ​​used in web programming.

If there are too many errors, for example, visitors regularly visit the erroneous country page - you can simply change the value of * catch-errors-p * so that you can easily understand the errors that have come to you.

 (defparameter *catch-errors-p* nil) (defclass debuggable-acceptor (hunchentoot:acceptor) ()) (defmethod hunchentoot:acceptor-request-dispatcher ((acceptor debuggable-acceptor)) (if *catch-errors-p* (call-next-method) (let ((dispatcher (handler-bind ((error #'invoke-debugger)) (call-next-method)))) (lambda (request) (handler-bind ((error #'invoke-debugger)) (funcall dispatcher request)))))) (defun request-dispatcher (request) "Hello!") (defparameter *debuggable-acceptor* (make-instance 'debuggable-acceptor :request-dispatcher 'request-dispatcher :port 4242)) (hunchentoot:start *debuggable-acceptor*) (setf hunchentoot:*handle-http-errors-p* nil) 


The request-dispatcher function is called with each incoming request and in our case simply returns “Hello!” - we will talk about its expansion in the next article.

If you have read this far you should put a bottle for you
beer , and even raised a test site on a lisp - I’m
I envy you! Acquaintance with lisp gave me almost a year and a half
enjoying this amazing language - and in this respect you have all
in front. Happy hacking!

Source: https://habr.com/ru/post/111365/


All Articles