{"size": 1966, "ext": "scrbl", "max_stars_repo_path": "web-server-doc/web-server/scribblings/soft.scrbl", "max_stars_repo_name": "jessealama/web-server", "max_stars_repo_stars_event_min_datetime": "2015-01-21T08:11:58.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-20T08:28:39.000Z", "max_issues_repo_path": "web-server-doc/web-server/scribblings/soft.scrbl", "max_issues_repo_name": "jessealama/web-server", "max_issues_repo_issues_event_min_datetime": "2015-01-14T08:06:37.000Z", "max_issues_repo_issues_event_max_datetime": "2022-02-12T14:38:40.000Z", "max_forks_repo_path": "web-server-doc/web-server/scribblings/soft.scrbl", "max_forks_repo_name": "jessealama/web-server", "max_forks_repo_forks_event_min_datetime": "2015-03-05T15:07:36.000Z", "max_forks_repo_forks_event_max_datetime": "2021-07-30T18:59:25.000Z"}
{"max_stars_count": 82, "max_issues_count": 105, "max_forks_count": 37, "avg_line_length": 25.5324675325, "max_line_length": 128, "alphanum_fraction": 0.6754832146}
#lang scribble/doc
@(require "web-server.rkt"
          (for-label web-server/http
                     web-server/lang/soft
                     web-server/lang/web))

@title[]{Soft State}

@defmodule[web-server/lang/soft]{

Sometimes you want to reference a large data-structure from a stateless program without the data-structure being serialized 
and increasing the size of the serialization. This module provides support for this scenario.

@defproc[(soft-state? [v any/c])
         boolean?]{
 Determines if @racket[v] is a soft state record.
}
                  
@defproc[(make-soft-state [thnk (-> any/c)])
         soft-state?]{
 Creates a piece of soft state that is computed by @racket[thnk]. This value is serializable.
}

@defproc[(soft-state-ref [ss soft-state?])
         any/c]{
 Extracts the value associated with @racket[ss]. If the value is not
 available (perhaps because of garbage collection, deserialization in an
 uninitialized process, etc), then the thunk associated with @racket[ss]
 is invoked and the value is cached.
}

@defform[(soft-state expr ...)]{
 Equivalent to @racket[(make-soft-state (lambda () expr ...))].
}

Here's an example servlet that uses soft state:
@racketmod[
 web-server
 
 (provide interface-version start) 
 (define interface-version 'stateless)
 
 (define softie
   (soft-state
    (printf "Doing a long computation...\n")
    (sleep 1)))
 
 (define (start req)
   (soft-state-ref softie)
   (printf "Done\n")
   (start
    (send/suspend
     (lambda (k-url)
       (response/xexpr
        `(html (body (a ([href ,k-url]) "Done"))))))))
]

When this is run and the link is clicked a few times, the output is:
@verbatim{
$ plt-web-server -p 8080
Doing a long computation...
Done
Done
Done
Done
}

If the server is restarted or the hostname in the URL is changed to a different host with the same code, and the URL is clicked:
@verbatim{
^Cuser break
$ plt-web-server -p 8080
Doing a long computation...
Done
}

}
