Tell me if you've done this before. You write up a nice little prototype of an idea in Livebook. You then get distracted by life situations like eating, writing an email, or taking a nap. You feel the need to close Livebook or prune the multiple sessions you've had running for weeks now. Because you have a million tabs open (with a session manager) and too many in Livebook to individually check, you restart your computer and let it crash(TM). When you open up Livebook again, "Oh. Shiiiiit" you exclaim. Where the hell did that notebook go? I'm 100% sure I clicked the disk icon, what the hell? If you're like me, you may have created this forked Livebook from memory, possibly taking a better approach.
There is a better way to handle this scenario. Livebook has had autosaves since 0.4:
The feature was added in this PR according to the changelog:
https://github.com/livebook-dev/livebook/pull/736
To find your autosave files:
For the Desktop application and CLI in production: ~/Library/Application Support/livebook/autosaved/
.
/Users/jbrayton/Library/Application Support/livebook/autosaved/
.For the dev environment: in config/dev.exs
, this is set as config :livebook, :data_path, Path.expand("tmp/livebook_data/dev"
.
/Users/Shared/repositories/personal/elixir/livebook/tmp/livebook_data/dev/autosaved/
.For the test environment: in config/test.exs
this is set as Path.expand("tmp/livebook_data/test")
.
/Users/Shared/repositories/personal/elixir/livebook/tmp/livebook_data/test/autosaved/
.Notebooks are saved by day in the autosave directory and the date corresponds to when they were created (when you immediately click the New notebook button).
To view or change your autosave directory in the CLI:
Settings
under the Home
and Learn
links.For the Desktop application, the port will be randomized but you can either change the URL to tack on /settings
after the port or click around to the settings page as described earlier.
If you are curious as to how this setting gets configured, we can start by looking at Livebook.Settings.default_autosave_path()
in https://github.com/livebook-dev/livebook/blob/main/lib/livebook/settings.ex#L32-L34.
We follow Livebook.Config.data_path()
to https://github.com/livebook-dev/livebook/blob/main/lib/livebook/config.ex#L76-L78 then the Erlang function :filename.basedir(:user_data, "livebook")
.
Running this in Livebook we get the output "/Users/jbrayton/Library/Application Support/livebook"
, precisely where the desktop app stores its files.
What lead me to this discovery, after vaguely remembering autosave was a thing, was looking for files on my computer.
I purposefully install and use the locate
command because I find it far easier to use than remembering the find -name
syntax.
Here's the output for checking that the word autosave
is in any directory or file name:
⋊> ~ locate autosaved/
/Users/Shared/repositories/personal/elixir/livebook/tmp/livebook_data/dev/autosaved/2022_10_31/18_25_03_mapset_drills_hedh.livemd
/Users/Shared/repositories/personal/elixir/livebook/tmp/livebook_data/dev/autosaved/2022_11_03/18_12_21_teller_bank_challenge_pv4e.livemd
/Users/Shared/repositories/personal/elixir/livebook/tmp/livebook_data/dev/autosaved/2022_11_03/18_13_39_untitled_notebook_pidb.livemd
/Users/Shared/repositories/personal/elixir/livebook/tmp/livebook_data/dev/autosaved/2022_11_03/19_31_57_dockyard_academy_amas_p75r.livemd
/Users/Shared/repositories/personal/elixir/livebook/tmp/livebook_data/dev/autosaved/2022_11_03/20_02_17_intro_to_timescale_jm7r.livemd
/Users/Shared/repositories/personal/elixir/livebook/tmp/livebook_data/dev/autosaved/2022_11_08/11_10_21_untitled_notebook_ervg.livemd
/Users/Shared/repositories/personal/elixir/livebook/tmp/livebook_data/dev/autosaved/2022_11_22/19_15_12_untitled_notebook_p75e.livemd
What I found interesting was that my files in ~/Library/Application Support/livebook/autosaved/
did not show up.
Had I not realized there could be different locations, I may have overlooked the notebook I was looking for all along.
I have no clue why locate
doesn't scour the directories in ~/Library
it should have access to but that's a problem for another day.
Originally, I wrote up a post trying to give a 2020 - 2021 overview that got hosed with a local git repo of this blog. I'm using the moment to remind myself that backups are important. It's also important to complete ideas for posts or journals quickly, even if something doesn't feel complete. Letting those linger for days without a git commit that hit the server is a genuine problem and I need to at the very least create and push to a new branch often.
One change that happened at the end of 2020, I started the journal section to try to capture bite-sized rough ideas. I had started a journal at work with notes in files like Phoenix Developer Diary.txt
and I looked for a solution to merge my different diaries. The excellent Claire Codes has an extremely consistent diary at clairecodes and served as my main source of inspiration.
I've gone all-in learning Elixir by participating in my first Advent of Code in 2020. I tapered off pretty quickly as I had serious problems working through loops and control flow. Seeing other examples on Elixir Forum helped immensely as I had slowly gotten better at reading the code. Later on in the year, I decided to take a TodoMVC sample through to a LiveView version with a little help from other resources on the internet. I had also started a diary where I wanted to capture the approaches I took each day I worked on the example. I have a plan to try to tackle my version from scratch but I'm also looking at other application ideas.
While the Advent of Code and TodoMVC was good to get my feet wet, I learned far more by pushing through Exercism exercises. If you're on Exercism and curious, my solutions can be found here. I highly recommend using Exercism to learn any language it covers as the recently released version 3 makes for a great experience. Exercises feel a bit more "real world" and less like brain teasers that happen to use programming concepts. Even if I happened to look at the HINTS.md
file, it never felt like cheating as it would only guide us toward a solution, not implement it.
After attending the excellent ElixirConf 2021 virtually, I've started working with Livebook in a few examples. I wanted to highlight the 3 notebooks that use the excellent spider_man
package to crawl 3 websites: Elixir Jobs, Elixir Radar Jobs, and Elixir Companies. Parsing the DOM of each required slowly stretching far outside my comfort zone. It's also worth mentioning that in the Elixir Jobs
example, I left a problem I found under the Sorting the Results
section. Due to the zero-width space, the section throws the message ** (SyntaxError) nofile:5:1: unexpected token: "" (column 1, code point U+200B)
.
Coming to the end of 2021, I'm looking forward to immersing myself deeper in the Elixir ecosystem. Livebook is also a great way to get your feet wet with Elixir concepts, like a powerful language scratchpad. There have been other life changes since January 2020 but those deserve separate posts when I can get to them. Fortunately, the pandemic hasn't been harsh on my family or extended family at all, which I consider an extreme blessing. I can't say we weren't impacted by the last 2 years but things could've been much worse.