<commit_before>#+TITLE:     Developing with Immutant

* Introduction

  Immutant fully embraces the time-honored Lisp tradition of
  incremental development at a REPL. This effectively puts you
  /inside/ the application server, with all its integrated services at
  your fingertips.

  It is quite an intimate experience to build your application while
  it's deployed and running in Immutant, with frictionless access to
  its services in real-time, running tests against those services
  immediately, as you edit them. And no mocking, packaging, or
  deployment steps to interrupt your flow.

* In-Container Testing
  
  At the REPL, you're free to use whichever Clojure testing library
  you prefer, e.g. =clojure.test= or [[https://github.com/marick/Midje][Midje]]. Each has its own way of
  invoking tests, allowing you to, for example, run one at a time or
  perhaps run every test in one or more namespaces. These should work
  fine at the Immutant REPL, and you're free to refer to the
  integrated Immutant services in your test definitions.

  There are some handy reflective functions available in the
  [[./apidoc/immutant.util.html][immutant.util]] namespace, specifically =app-uri=, which can be used
  to construct URL's in the tests for your web apps. This ensures
  your tests can always "find" your app, regardless of context
  path or HTTP port, for example.

** lein immutant test

   The =test= task of the [[https://github.com/immutant/lein-immutant/][lein-immutant]] plugin is how you run your
   in-container tests /outside/ of Immutant. It will find all your
   tests (or Midje facts), fire up an Immutant instance, deploy your
   app to it, connect to its REPL, run all the tests, and display the
   results, returning success only if all the tests pass. It should be
   run on the Continuous Integration server for your app whenever any
   changes are committed.

* The REPL
  :PROPERTIES:
  :CUSTOM_ID: interactive
  :END:

  Immutant provides two methods for connecting to an application's runtime
  with a REPL: Swank (for emacs & possibly vim if you are feeling adventurous)
  and nREPL (for any nREPL client).

  Each REPL service runs on a unique port, allowing you to have REPLs into
  multiple applications within the same Immutant, or multiple REPLs within the
  same application.

  REPL services can be started at application deploy time, or dynamically from
  application code. REPLs started dynamically can be also be shutdown
  dynamically. REPLs started at deploy time and any dynamically started REPLs
  that are not shut down by the application will be shut down when the
  application is undeployed.

  See [[./initialization.html#initialization-configuration][initialization configuration]] for a list of configuration options
  (like =:swank-port= and =:nrepl-port=) and how to apply them.

** Binding To An Interface
   :PROPERTIES:
   :CUSTOM_ID: interactive-binding
   :END:

   AS7 is setup to use multiple network interfaces, and allows you to specify
   different interfaces for your server: /public/, /management/, and /unsecure/.
   By default, these interfaces are all the same - =127.0.0.1=. But you can
   specify different addresses for each named interface, aiding in the security
   setup of your management ports.

   By default, the repl services started by Immutant bind to the /management/
   interface.

** nREPL

   [[https://github.com/clojure/tools.nrepl][nREPL]] is a client/server protocol that provides a Clojure REPL
   across a network. It has several clients that support it.

*** Starting nREPL

    You can start an nREPL service using one (or both) of two methods:
    specifying =:nrepl-port= and/or =:nrepl-interface= options in your
    configuration, or by calling [[./apidoc/immutant.repl.html#var-start-nrepl][immutant.repl/start-nrepl]] from
    application code.

    To have Immutant start a nREPL service on your behalf, you can specify
    one or both of the following options:

    | Option             | Default                                                              | Description                                                                                                            |
    |--------------------+----------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------|
    | =:nrepl-port=      | none, =0= if =:dev= profile is active or =:nrepl-interface= provided | The port for binding the nREPL endpoint. =0= means "any available port"                                                |
    | =:nrepl-interface= | none, =:management= if =:nrepl-port= provided                        | Can be one of =:public=, =:management=, or =:unsecure=, or an ip address string. See the section on [[#interactive-binding][interface aliases]]. |
   
    If =:nrepl-port= is set to 0, the choice of an available port is
    delegated to the operating system. Immutant will start up an nREPL
    service using that port, and write it to a file beneath your
    project's =target/= directory called =repl-port= and also to a
    file in the root of the project called =.nrepl-port=, following
    Leiningen's convention. Many nREPL clients will use one of these
    files to establish a connection. Both will be deleted when the
    Immutant process exits.

    When the =:dev= profile is active, =:nrepl-port= defaults to 0.
    This means that, by default, every application you deploy will
    have its own dedicated nREPL, and most nREPL clients will
    automatically detect and connect to it using the files mentioned
    above.

    To prevent the nREPL server from starting by default, simply
    deploy your application without the =:dev= profile active, or set
    =:nrepl-port= to =nil=.

    You can also start an nREPL service from your own code, which is
    useful if you need to start it in response to a runtime event or
    bind to an interface other than the [[#interactive-binding][management interface]]. To do
    so, simply call [[./apidoc/immutant.repl.html#var-start-nrepl][immutant.repl/start-nrepl]]. nREPL allows you to
    have multiple services in the same runtime, so you need to save
    the return value of =start-nrepl= if you want to shut down the
    nREPL service yourself:

    #+begin_src clojure
      ;; bind to the given port on the management interface, and
      ;; save the service handle for later
      (def nrepl (immutant.repl/start-nrepl 4242))
      
      ;; bind to the given port and interface
      (immutant.repl/start-nrepl "127.0.0.1" 4242)

      ;; bind to the given port on the :public interface
      (immutant.repl/start-nrepl :public 4242)
    #+end_src

*** Connecting to nREPL

**** Via Emacs
    :PROPERTIES:
    :CUSTOM_ID: interactive-nrepl-emacs
    :END:

     To connect to nREPL from Emacs, first install [[https://github.com/kingtim/nrepl.el][nrepl.el]], then connect
     to your running nREPL via the =nrepl= function (=M-x nrepl RET=). 
     It will prompt you for the host and port, and if you're
     somewhere beneath your project, it should default you with the
     correct port.

**** Via Leiningen

     [[http://leiningen.org/][Leiningen]] provides a REPL client (based on [[https://github.com/trptcolin/reply][reply]], an enhanced REPL
     client) that supports connecting to an nREPL service:

     #+begin_src sh
       # connect to an nREPL bound to port 4242 on localhost
       $ lein repl :connect 4242 
             
       # connect to an nREPL bound to port 4242 on 10.0.0.10
       $ lein repl :connect 10.0.0.10:4242 

       # if inside the project directory
       $ lein repl :connect
     #+end_src
     
**** Via Counterclockwise

     [[http://code.google.com/p/counterclockwise/][Counterclockwise]] is an Eclipse plugin for Clojure development. You can
     use it to connect to your Immutant nREPL session via /Window/ -> 
     /Connect to REPL/. It will prompt you for an ip address and port to 
     connect to.

*** Shutting Down nREPL

    Immutant will automatically shutdown any nREPL services for you when your
    application is undeployed, but if you need to do so before undeploy you
    can do so using the [[./apidoc/immutant.repl.html#var-stop-nrepl][immutant.repl/stop-nrepl]] function. You'll need to
    pass it the service handle returned by the =start-nrepl= call:
<commit_msg>Clean up nrepl docs a smidge.<commit_after>#+TITLE:     Developing with Immutant

* Introduction

  Immutant fully embraces the time-honored Lisp tradition of
  incremental development at a REPL. This effectively puts you
  /inside/ the application server, with all its integrated services at
  your fingertips.

  It is quite an intimate experience to build your application while
  it's deployed and running in Immutant, with frictionless access to
  its services in real-time, running tests against those services
  immediately, as you edit them. And no mocking, packaging, or
  deployment steps to interrupt your flow.

* In-Container Testing
  
  At the REPL, you're free to use whichever Clojure testing library
  you prefer, e.g. =clojure.test= or [[https://github.com/marick/Midje][Midje]]. Each has its own way of
  invoking tests, allowing you to, for example, run one at a time or
  perhaps run every test in one or more namespaces. These should work
  fine at the Immutant REPL, and you're free to refer to the
  integrated Immutant services in your test definitions.

  There are some handy reflective functions available in the
  [[./apidoc/immutant.util.html][immutant.util]] namespace, specifically =app-uri=, which can be used
  to construct URL's in the tests for your web apps. This ensures
  your tests can always "find" your app, regardless of context
  path or HTTP port, for example.

** lein immutant test

   The =test= task of the [[https://github.com/immutant/lein-immutant/][lein-immutant]] plugin is how you run your
   in-container tests /outside/ of Immutant. It will find all your
   tests (or Midje facts), fire up an Immutant instance, deploy your
   app to it, connect to its REPL, run all the tests, and display the
   results, returning success only if all the tests pass. It should be
   run on the Continuous Integration server for your app whenever any
   changes are committed.

* The REPL
  :PROPERTIES:
  :CUSTOM_ID: interactive
  :END:

  Immutant provides two methods for connecting to an application's runtime
  with a REPL: Swank (for emacs & possibly vim if you are feeling adventurous)
  and nREPL (for any nREPL client).

  Each REPL service runs on a unique port, allowing you to have REPLs into
  multiple applications within the same Immutant, or multiple REPLs within the
  same application.

  REPL services can be started at application deploy time, or dynamically from
  application code. REPLs started dynamically can be also be shutdown
  dynamically. REPLs started at deploy time and any dynamically started REPLs
  that are not shut down by the application will be shut down when the
  application is undeployed.

  See [[./initialization.html#initialization-configuration][initialization configuration]] for a list of configuration options
  (like =:swank-port= and =:nrepl-port=) and how to apply them.

** Binding To An Interface
   :PROPERTIES:
   :CUSTOM_ID: interactive-binding
   :END:

   AS7 is setup to use multiple network interfaces, and allows you to specify
   different interfaces for your server: /public/, /management/, and /unsecure/.
   By default, these interfaces are all the same - =127.0.0.1=. But you can
   specify different addresses for each named interface, aiding in the security
   setup of your management ports.

   By default, the repl services started by Immutant bind to the /management/
   interface.

** nREPL

   [[https://github.com/clojure/tools.nrepl][nREPL]] is a client/server protocol that provides a Clojure REPL
   across a network. It has several clients that support it.

*** Starting nREPL

    You can start an nREPL service using one (or both) of two methods:
    specifying =:nrepl-port= and/or =:nrepl-interface= options in your
    configuration, or by calling [[./apidoc/immutant.repl.html#var-start-nrepl][immutant.repl/start-nrepl]] from
    application code.

    To have Immutant start a nREPL service on your behalf, you can specify
    one or both of the following options:

    | Option             | Default                                                              | Description                                                                                                            |
    |--------------------+----------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------|
    | =:nrepl-port=      | none, =0= if =:dev= profile is active or =:nrepl-interface= provided | The port for binding the nREPL endpoint. =0= means "any available port"                                                |
    | =:nrepl-interface= | none, =:management= if =:nrepl-port= provided                        | Can be one of =:public=, =:management=, or =:unsecure=, or an ip address string. See the section on [[#interactive-binding][interface aliases]]. |
   
    If =:nrepl-port= is set to 0, the choice of an available port is
    delegated to the operating system. Immutant will start up an nREPL
    service using that port, and write it to a file beneath your
    project's =target/= directory called =repl-port= and also to a
    file in the root of the project called =.nrepl-port=, following
    Leiningen's convention. Many nREPL clients will use one of these
    files to establish a connection. Both will be deleted when the
    Immutant process exits.

    When the =:dev= profile is active, =:nrepl-port= defaults to 0.
    This means that, by default, every application you deploy will
    have its own dedicated nREPL, and most nREPL clients will
    automatically detect and connect to it using the files mentioned
    above.

    To prevent the nREPL server from starting by default, simply
    deploy your application without the =:dev= profile active, or set
    =:nrepl-port= to =nil=.

    You can also start an nREPL service from your own code, which is
    useful if you need to start it in response to a runtime event. To
    do so, simply call [[./apidoc/immutant.repl.html#var-start-nrepl][immutant.repl/start-nrepl]]. nREPL allows you to
    have multiple services in the same runtime, so you need to save
    the return value of =start-nrepl= if you want to shut down the
    nREPL service yourself:

    #+begin_src clojure
      ;; bind to the given port on the management interface, and
      ;; save the service handle for later
      (def nrepl (immutant.repl/start-nrepl 4242))
      
      ;; bind to the given port and interface
      (immutant.repl/start-nrepl "127.0.0.1" 4242)

      ;; bind to the given port on the :public interface
      (immutant.repl/start-nrepl :public 4242)
    #+end_src

*** Connecting to nREPL

**** Via Emacs
    :PROPERTIES:
    :CUSTOM_ID: interactive-nrepl-emacs
    :END:

     To connect to nREPL from Emacs, first install [[https://github.com/clojure-emacs/cider][cider]] (formerly
     nrepl.el), then connect to your running nREPL via the =nrepl=
     function (=M-x nrepl RET=).  It will prompt you for the host and
     port, and if you're somewhere beneath your project, it should
     default you with the correct port.

**** Via Leiningen

     [[http://leiningen.org/][Leiningen]] provides a REPL client (based on [[https://github.com/trptcolin/reply][reply]], an enhanced REPL
     client) that supports connecting to an nREPL service:

     #+begin_src sh
       # connect to an nREPL bound to port 4242 on localhost
       $ lein repl :connect 4242 
             
       # connect to an nREPL bound to port 4242 on 10.0.0.10
       $ lein repl :connect 10.0.0.10:4242 

       # if inside the project directory
       $ lein repl :connect
     #+end_src
     
**** Via Counterclockwise

     [[http://code.google.com/p/counterclockwise/][Counterclockwise]] is an Eclipse plugin for Clojure development. You can
     use it to connect to your Immutant nREPL session via /Window/ -> 
     /Connect to REPL/. It will prompt you for an ip address and port to 
     connect to.

*** Shutting Down nREPL

    Immutant will automatically shutdown any nREPL services for you when your
    application is undeployed, but if you need to do so before undeploy you
    can do so using the [[./apidoc/immutant.repl.html#var-stop-nrepl][immutant.repl/stop-nrepl]] function. You'll need to
    pass it the service handle returned by the =start-nrepl= call:

{'fraction_non_alphanumeric': 0.09343735111958075, 'fraction_numerical': 0.006788947117675083, 'mean_word_length': 2.6875274483970135, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 10, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 8, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '637780', 'n_tokens_mistral': 4781, 'n_tokens_neox': 4544, 'n_words': 2107}