{"id":13647042,"url":"https://github.com/fbsamples/ghc-hotswap","last_synced_at":"2025-04-21T21:32:17.607Z","repository":{"id":39615787,"uuid":"104127386","full_name":"fbsamples/ghc-hotswap","owner":"fbsamples","description":"Example code for how we swap compiled code within a running Haskell process.","archived":true,"fork":false,"pushed_at":"2018-09-24T20:34:23.000Z","size":13,"stargazers_count":172,"open_issues_count":2,"forks_count":10,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-10-02T02:24:28.187Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fbsamples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-19T20:52:31.000Z","updated_at":"2024-01-03T18:12:26.000Z","dependencies_parsed_at":"2022-09-12T23:50:11.675Z","dependency_job_id":null,"html_url":"https://github.com/fbsamples/ghc-hotswap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fbsamples%2Fghc-hotswap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fbsamples%2Fghc-hotswap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fbsamples%2Fghc-hotswap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fbsamples%2Fghc-hotswap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fbsamples","download_url":"https://codeload.github.com/fbsamples/ghc-hotswap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223776302,"owners_count":17200625,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T01:03:19.027Z","updated_at":"2024-11-09T20:30:57.032Z","avatar_url":"https://github.com/fbsamples.png","language":"Haskell","readme":"GHC.Hotswap\n===========\n\nDemonstrates how to build an application that can hot-swap parts of itself at runtime, using GHC. This is a standalone illustration of the technology used in production in the [Sigma system at Facebook](https://code.facebook.com/posts/745068642270222/fighting-spam-with-haskell/).\n\nThere are a handful of Haskell packages here:\n\n * [ghc-hotswap](ghc-hotswap): Core library for swapping shared objects safely\n * [ghc-hotswap-demo](ghc-hotswap-demo): Demo program that shows up swapping\n * [ghc-hotswap-so](ghc-hotswap-so): Sample cabal project for building a shared object\n * [ghc-hotswap-types](ghc-hotswap-types): Common libraries between the `so` and `demo` packages\n\n# ghc-hotswap\n\nShared object swapping goodness.\n\n# Demo\n\nQuick Start\n-----------\n\n### Build *types*\n  1. cd ghc-hotswap-types\n  2. cabal configure\n  3. cabal install\n### Build *hotswap*\n  1. cd ghc-hotswap\n  2. cabal configure\n  3. cabal install\n### Build *so*\n  1. cd ghc-hotswap-so\n  2. cabal configure --enable-library-for-ghci\n  3. cabal build\n(Note the file path of `dist/build/HSghc-hotswap-so(...).o`)\n### Run demo\n  1. cd ghc-hotswap-demo\n  2. cabal configure\n  3. cabal build\n  4. cabal run \u003cpath of first .o file\u003e\n\n## ghc-hotswap-types\n\nExample library for common types between the main binary and shared object. The object code for this library will end up in the final binary, but the shared object needs to know what types to generate at the API boundary.\n\nNo special configuration for this library\n\n- cabal configure\n- cabal install\n\n## ghc-hotswap\n\nGeneral library for loading and consecutively updating shared objects in a concurrency-safe manner.\n\nNo special configuration for this library\n\n- cabal configure\n- cabal install\n\n## ghc-hotswap-so\n\nExample shared object library. Constains:\n\n  * `Handles` [module](ghc-hotswap-so/SO/Handles.hs) defining a function that returns a StablePtr to our expected API object and exports a c-symbol for it.\n  * `MyCode` [module](ghc-hotswap-so/SO/MyCode.hs) as an example of complex library code that can be updated quickly\n\nThe main purpose is to generate an object file that another binary will know how to dynamically open. The `--enable-library-for-ghci` cabal flag does this for us.\n\n- cabal configure --enable-library-for-ghci\n- cabal build\n\nThe file we care about gets placed in `ghc-hotswap-so/dist/build/` with a filename prefix like `HSghc-hotswap-so` and extension `.o`. The path to this file is important (or copy it to a nicer location for yourself) as you'll need it later.\n\n## ghc-hotswap-demo\n\nDemo executable for loading + unloading shared objects on the fly.\n\nNote the configuration set [in ghc-hotswap-demo.cabal](ghc-hotswap-demo/ghc-hotswap-demo.cabal). It does not depend on `ghc-hotswap-so` and adds `-rdynamic` and `-fwhole-archive-hs-libs` as GHC flags.\n\n- cabal configure\n- cabal run \u003cpath-of-first-.o\u003e\n\nThe program loads in the first shared object and periodically prints some information. It's waiting for input on stdin for the path of the next shared object to use.\n\n  * Go back to ghc-hotswap-so\n  * Edit `SO/Handles.hs` or `SO/MyCode.hs` to do as you want\n  * Rebuild the object file (`cabal build`)\n  * Copy the desired `.o` file somewhere friendlier\n  * Send the full path of the `.o` to stdin of the demo program\n  * See the output of the program change live\n  * ???\n  * Profit!\n","funding_links":[],"categories":["Haskell"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffbsamples%2Fghc-hotswap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffbsamples%2Fghc-hotswap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffbsamples%2Fghc-hotswap/lists"}