From 7ec4c7620a96614edfd3141503e37f09183cb970 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Tue, 1 Dec 2020 12:55:35 -0400
Subject: [PATCH 01/45] Adds Red Moon
---
pages/data/books.json | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/pages/data/books.json b/pages/data/books.json
index e0e3ef3..c130b32 100644
--- a/pages/data/books.json
+++ b/pages/data/books.json
@@ -155,6 +155,19 @@
"Pages": 256,
"CoverURL": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1333578746l/3869.jpg",
"GoodreadsURL": "https://www.goodreads.com/book/show/3869.A_Brief_History_of_Time"
+ },
+ {
+ "Title": "Red Moon",
+ "Subtitle": "",
+ "Author": "Kim Stanley Robinson",
+ "Published": "",
+ "Status": "Completed",
+ "Category": "Fiction",
+ "SubCategory": "Science Fiction",
+ "Rating": 4,
+ "Pages": 446,
+ "CoverURL": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1520263303l/38496710._SY475_.jpg",
+ "GoodreadsURL": "https://www.goodreads.com/book/show/38496710-red-moon"
}
]
}
From baaa2c5a6ff735c945f969c8cf53700e51440ba5 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 5 Feb 2021 20:20:05 -0400
Subject: [PATCH 02/45] New year, new things
---
pages/aws-good-parts.md | 7 +++++++
pages/books.jinja2 | 17 +++++++---------
pages/data/books.json | 43 +++++++++++++++++++++++++++++++++++++++-
pages/gadventures.jinja2 | 4 ++--
templates/index.html | 10 ++++------
5 files changed, 62 insertions(+), 19 deletions(-)
diff --git a/pages/aws-good-parts.md b/pages/aws-good-parts.md
index 269a071..7dc4a9c 100644
--- a/pages/aws-good-parts.md
+++ b/pages/aws-good-parts.md
@@ -134,6 +134,13 @@ time. It is incomplete, but figured I'd push what I have so far.
* More or less twice as expensive for on-demand but prices drop quite quickly
when looking at reserved instances.
+## Redshift
+
+* Fully managed petabyte-scale (big!) data warehouse service
+* Redshift Spectrum is a feature available in Redshift which allows querying of S3 data
+ directly.
+*
+
## Appendix
diff --git a/pages/books.jinja2 b/pages/books.jinja2
index 0d2b56c..7563ea9 100644
--- a/pages/books.jinja2
+++ b/pages/books.jinja2
@@ -3,22 +3,19 @@ date: 09-03-2020
data: data/books.json
---
-
I've set a goal of reading 12 books in 2020. On this page, I list the books I
-have read, am reading, or failed to read (started, couldn't finish)
+
+
In 2020, I set a goal to read 12 books. To many people, that's not much but I hadn't completed a book in awhile (mostly using my reading capacity for online articles). I logged 13, completed 11 of those (or 3,395 pages), and started a couple more.
+
I haven't set a goal in 2021 but continue to dedicate time to reading. We'll see how it goes!
+
-
I have a bad habit of reading plenty of 5-10 minute pieces, love anything
-technical, and consume plenty of podcasts. However,
-I struggle to sit down with a book. Taking my time back is an important goal of
-2020 for me, hence the need to sit down and read.
-
-
2020 Book shelf
+
Book Shelf
- {% for book in books %}
+ {% for book in books|sort(attribute="Date", reverse=True) %}
I've been at G Adventures for nearly 9 years. I've grown up at this company
-and it has formed who I am. Consider this a mini resume with some fun stats
+
I spent over 9 years of my career at G Adventures. I grew up at this company
+and it formed who I am. Consider this a mini resume with some fun stats
thrown in.
I'm a 30-something Polish-Canadian dude who's lived in many places and visited
+
I'm a 30-something Polish-Canadian who's lived in many places and visited
plenty more. Born in Poland, mostly raised in Ontario, and now live in
Halifax, Nova Scotia. Apart from building things, I spend most of my time
being a father, cooking, travelling, and nerding out over (and advocating for!) public transit
A little more about me
-
I work at G Adventures, a
- travel company focused on community tourism and using travel as a means of wealth distribution.
+
During the day, I work at Wattpad as a platform engineer. I write Go, support clients interfacing with our platform, and stare at data. Previously,
+ I spent many years at G Adventures.
- I've been at G for awhile and have compiled a mini G resume, here
-
-
\n\n' % code
+ joined_lines = "\n".join(lines)
+ joined_lines = self.pattern.sub(repl, joined_lines)
+ return joined_lines.split("\n")
+
+class CodeBlockExtension(Extension):
+ def extendMarkdown(self, md, md_globals):
+ md.preprocessors.add('CodeBlockPreprocessor', CodeBlockPreprocessor(), '_begin')
+
+
diff --git a/pages/golang-context-wg-go-routines.md b/pages/golang-context-wg-go-routines.md
new file mode 100644
index 0000000..ec1bbee
--- /dev/null
+++ b/pages/golang-context-wg-go-routines.md
@@ -0,0 +1,350 @@
+title: Using Go's Context and WaitGroups to gracefully handle goroutines
+date: 02-15-2021
+
+---
+
+Recently I was building a application that would tick on an interval and on each tick,
+produce potentially thousands of goroutines. I wanted to ensure when the application was terminated, it would exit gracefully and quickly, even if particular goroutines were processing slowly.
+
+Initially, I was using `sync.WaitGroup` to control flow, primarily around how I log
+output, but I quickly realized that if I created many goroutines and even a small
+collection of them did not return immediately, my application would hang when being
+terminated. This led me to reviewing `context.WithCancel` and understanding how I can
+adjust my application to be well suited for quick and graceful termination!
+
+We can demonstrate this by building up from an application which, initially, does not use
+either:
+
+[sourcecode:go]
+ package main
+
+ import (
+ "fmt"
+ "log"
+ "math/rand"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+ )
+
+ func doSomething(ch chan int) {
+ fmt.Printf("Received job %d\n", <-ch)
+ }
+
+ func init() {
+ rand.Seed(time.Now().Unix())
+ }
+
+ func main() {
+ var (
+ closing = make(chan struct{})
+ ticker = time.NewTicker(1 * time.Second)
+ logger = log.New(os.Stderr, "", log.LstdFlags)
+ batchSize = 6
+ jobs = make(chan int, batchSize)
+ )
+
+ go func() {
+ signals := make(chan os.Signal, 1)
+ signal.Notify(signals, syscall.SIGTERM, os.Interrupt)
+ <-signals
+ close(closing)
+ }()
+ loop:
+ for {
+ select {
+ case <-closing:
+ break loop
+ case <-ticker.C:
+ for n := 0; n < batchSize; n++ {
+ jobs <- n
+ go doSomething(jobs)
+ }
+ logger.Printf("Completed doing %d things.", batchSize)
+ }
+ }
+ }
+[/sourcecode]
+
+When the program is run, we observe the sequence of _"Received job ..."_ messages alongside the completion message (_"Completed doing .."_). It might look something like this:
+
+ Received job 0
+ Received job 1
+ Received job 2
+ 2021/02/08 21:30:59 Completed doing 6 things.
+ Received job 3
+ Received job 4
+ Received job 5
+ 2021/02/08 21:31:00 Completed doing 6 things.
+
+The results don't print consistently! This makes sense as we know that go routines
+won't block the lines beneath them unless we do something about it. We can add a
+`WaitGroup` to improve flow. First, define it in the `var` block:
+
+ [sourcecode:go]
+ var (
+ ..
+ wg sync.WaitGroup
+ )
+ [/sourcecode]
+
+Adjust the loop:
+
+ [sourcecode:go]
+ for n := 0; n < batchSize; n++ {
+ wg.Add(1)
+ jobs <- n
+ go doSomething(&wg, jobs)
+ }
+ wg.Wait()
+ logger.Printf("Completed doing %d things.", batchSize)
+ [/sourcecode]
+
+And finally, the goroutine:
+
+ [sourcecode:go]
+ func doSomething(wg *sync.WaitGroup, ch chan int) {
+ defer wg.Done()
+ fmt.Printf("Received job %d\n", <-ch)
+ }
+ [/sourcecode]
+
+[WaitGroups](https://golang.org/pkg/sync/#WaitGroup) wait for a collection of
+goroutines to finish. If we read the code out loud, we can see that:
+
+1. On each iteration of the loop, we add `1` to the WaitGroup. We add `1`
+ because our goroutine will call `wg.Done()` once, which decrements the
+ WaitGroup counter by one. It balances out as each goroutine returns.
+2. Before the `logger` call, we add `wg.Wait()`. This tells our Go program to block
+ until the WaitGroup counter is zero. The counter will be zero when all
+ goroutines have called `wg.Done()`
+
+Simple, right? If we run the program again we can see the results print more
+consistently:
+
+ 2021/02/08 21:46:47 Completed doing 6 things.
+ Received job 0
+ Received job 1
+ Received job 2
+ Received job 4
+ Received job 5
+ Received job 3
+ 2021/02/08 21:46:48 Completed doing 6 things.
+ Received job 0
+ Received job 2
+ Received job 3
+ Received job 4
+ Received job 5
+ Received job 1
+
+By the way, it's expected the jobs won't be ordered! We haven't done anything to
+ensure that.
+
+Before we continue, run the application as it is thus far and try to terminate it,
+usually this is done by hitting `Control-d`. The program should exit without issue.
+
+To demonstrate further need for control, let's add a piece of code that's more akin to a real-world
+scenario. We'll make a new function which calls out to an API and expects a response.
+We'll then use `context.WithCancel` to cancel the request while it's in flight.
+
+First, create the new function without any context. It's going to be heavier,
+so follow the in-line commentary as necessary:
+
+ [sourcecode:go]
+ func doAPICall(wg *sync.WaitGroup) error {
+ defer wg.Done()
+
+ req, err := http.NewRequest("GET", "https://httpstat.us/200", nil)
+ if err != nil {
+ return err
+ }
+
+ // The httpstat.us API accepts a sleep parameter which sleeps the request for the
+ // passed time in ms
+ q := req.URL.Query()
+ sleepMin := 1000
+ sleepMax := 4000
+ q.Set("sleep", fmt.Sprintf("%d", rand.Intn(sleepMax-sleepMin)+sleepMin))
+ req.URL.RawQuery = q.Encode()
+
+ // Make the request to the API in an anonymous function, using a channel to
+ // communicate the results
+ c := make(chan error, 1)
+ go func() {
+ // For the purposes of this example, we're not doing anything with the response.
+ _, err := http.DefaultClient.Do(req)
+ c <- err
+ }()
+
+ // Block until the channel is populated
+ return <-c
+ }
+ [/sourcecode]
+
+Modify the ticker interval; remove the previous call to `doSomething`, optionally drop the
+`jobs` channel (we won't use it further), and add a call to `doAPICall`:
+
+ [sourcecode:go]
+ for n := 0; n < batchSize; n++ {
+ wg.Add(1)
+ go doAPICall(&wg)
+ }
+ [/sourcecode]
+
+Run the application and try to exit again. You'll notice two things:
+
+* The WaitGroup continues to wait until all go routines are finished. The `doAPICall`
+ function blocks until a response is returned from the `httpstat.us` API, and that can
+ range anywhere from `1000` to `4000` ms.
+* Depending on when you try to terminate the application, it can be difficult to do so (you may
+ not notice this on first pass, run it a few times and try to terminate at different
+ times)
+
+Now to demonstrate how `context.WithCancel` provides further control over program cancellation. When `context.WithCancel` is initialised, it provides a context and a `CancelFunc`. This cancel func can cancel the context, which sounds confusing at first pass; Reading [Go Concurrency Patterns: Context](https://blog.golang.org/context) from The Go Blog helped, and I recommend checking that out after this post!
+
+Ok, back to it. There's little that needs to be done to the application to have it support this
+cancellation flow. First, create a new context with cancellation function:
+
+ [sourcecode:go]
+ var (
+ ctx, cancel = context.WithCancel(context.Background())
+ ...
+ )
+ [/sourcecode]
+
+Then, in the anonymous function where we watch for program termination, call the `CancelFunc` after
+the `signals` channel is notified. This means that the context will be considered cancelled:
+
+ [sourcecode:go]
+ go func() {
+ signals := make(chan os.Signal, 1)
+ signal.Notify(signals, syscall.SIGTERM, os.Interrupt)
+ <-signals
+ logger.Println("Initiating shutdown of producer.")
+ cancel()
+ close(closing)
+ }()
+ [/sourcecode]
+
+Then, adjust the `doAPICall` function to accept a context, and modify the return statement
+to use a blocking `select`, waiting on either the `ctx.Done` channel or the request
+response. Parts of the function snipped for brevity:
+
+ [sourcecode:go]
+ func doAPICall(ctx context.Context, ....) {
+ // Cancel the request if ctx.Done is closed or await the response
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case err := <-c:
+ return err
+ }
+ }
+ [/sourcecode]
+
+Finally, ensure the call to `doAPICall` has been adjusted to pass the context. Now, run
+the application and terminate it at different start times.
+
+What happens now? The application terminates immediately. The blocking `select` call
+watches for the closure of `ctx.Done` or the response on `c`, whichever comes first. When
+the application is terminated, `ctx.Done` takes precedence and the function returns early,
+not concerning itself with the response of the request. The WaitGroup continues to do its
+specific job and the flow of the application during termination is much improved!
+
+There's many ways this can be expanded or used, so please consider it a starting point. I
+initially struggled understanding how I could use `WaitGroup` and `context.WithCancel` in
+combination, so I hope this was useful!
+
+For reference, here's the code in its entirety:
+
+ [sourcecode:go]
+ package main
+
+ import (
+ "context"
+ "fmt"
+ "log"
+ "math/rand"
+ "net/http"
+ "os"
+ "os/signal"
+ "sync"
+ "syscall"
+ "time"
+ )
+
+ func doAPICall(ctx context.Context, wg *sync.WaitGroup) error {
+ defer wg.Done()
+
+ req, err := http.NewRequest("GET", "https://httpstat.us/200", nil)
+ if err != nil {
+ return err
+ }
+
+ // The httpstat.us API accepts a sleep parameter which sleeps the request for the
+ // passed time in ms
+ q := req.URL.Query()
+ sleepMin := 1000
+ sleepMax := 4000
+ q.Set("sleep", fmt.Sprintf("%d", rand.Intn(sleepMax-sleepMin)+sleepMin))
+ req.URL.RawQuery = q.Encode()
+
+ c := make(chan error, 1)
+ go func() {
+ // For the purposes of this example, we're not doing anything with the response.
+ _, err := http.DefaultClient.Do(req)
+ c <- err
+ }()
+
+ // Block until either channel is populated or closed
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case err := <-c:
+ return err
+ }
+ }
+
+ func init() {
+ rand.Seed(time.Now().Unix())
+ }
+
+ func main() {
+ var (
+ closing = make(chan struct{})
+ ticker = time.NewTicker(1 * time.Second)
+ logger = log.New(os.Stderr, "", log.LstdFlags)
+ batchSize = 6
+ wg sync.WaitGroup
+ ctx, cancel = context.WithCancel(context.Background())
+ )
+
+ go func() {
+ signals := make(chan os.Signal, 1)
+ signal.Notify(signals, syscall.SIGTERM, os.Interrupt)
+ <-signals
+ cancel()
+ close(closing)
+ }()
+ loop:
+ for {
+ select {
+ case <-closing:
+ break loop
+ case <-ticker.C:
+ for n := 0; n < batchSize; n++ {
+ wg.Add(1)
+ go doAPICall(ctx, &wg)
+ }
+ wg.Wait()
+ logger.Printf("Completed doing %d things.", batchSize)
+ }
+ }
+ }
+ [/sourcecode]
+
+
+As a final note, a portion of this code was inspired by the [Go Concurrency Patterns:
+Context](https://blog.golang.org/context) blog post, which I, again, recommend. It
+introduces further controls like `context.WithTimeout` and well, the Go blog is a treasure that everyone should read!
diff --git a/requirements.txt b/requirements.txt
index d765008..7aeaf55 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,3 +2,4 @@ Flask==1.1.1
Frozen-Flask==0.15
Markdown==3.1.1
pyyaml==5.2
+pygments==2.8.0
diff --git a/static/base.css b/static/base.css
new file mode 100644
index 0000000..dae28c9
--- /dev/null
+++ b/static/base.css
@@ -0,0 +1,89 @@
+body {
+ margin: 1em 10em;
+ font-family: "Merriweather", "PT Serif", Georgia, "Times New Roman", serif;
+ margin: 0;
+ overflow-x: hidden;
+ padding: 1rem 0;
+}
+
+footer,
+header,
+main {
+ max-width: 1080px;
+ margin: 0 auto;
+ padding: 1rem 1rem;
+}
+
+section {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+
+h1 {
+ font-weight: 400;
+}
+
+h1 a { text-decoration: none; }
+h1 a:hover { text-decoration: underline; }
+
+p {
+ line-height: 1.4em;
+}
+
+li {
+ line-height: 1.4em;
+}
+
+.book-shelf {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+}
+
+.book {
+ padding: 20px;
+ max-width: 160px;
+}
+
+.book img {
+ max-width: 160px;
+}
+
+.book .title {
+ font-size: 1rem;
+}
+
+.book .subtitle {
+ font-size: 0.8rem;
+}
+
+.published-date {
+ font-size: 0.8rem;
+}
+
+article {
+ padding: 0 1rem;
+ border: 2px solid #6D5ACF;
+}
+
+article p>img {
+ max-height: 500px;
+ max-width: 100%;
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+ margin-left: auto;
+ margin-right: auto;
+ display: inline;
+}
+
+/* Customizations for pygments code rendering */
+.code {
+ background-color: #262626;
+}
+
+/* pygments (or Markdown, unsure) adds a at the end of each code block
+ * and it's not necessary. Hide only the last one */
+.code br:last-of-type {
+ display: none;
+}
diff --git a/static/pygments.css b/static/pygments.css
new file mode 100644
index 0000000..18edeeb
--- /dev/null
+++ b/static/pygments.css
@@ -0,0 +1,76 @@
+pre { line-height: 125%; }
+td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.hll { background-color: #49483e }
+.c { color: #75715e } /* Comment */
+.err { color: #960050; background-color: #1e0010 } /* Error */
+.k { color: #66d9ef } /* Keyword */
+.l { color: #ae81ff } /* Literal */
+.n { color: #f8f8f2 } /* Name */
+.o { color: #f92672 } /* Operator */
+.p { color: #f8f8f2 } /* Punctuation */
+.ch { color: #75715e } /* Comment.Hashbang */
+.cm { color: #75715e } /* Comment.Multiline */
+.cp { color: #75715e } /* Comment.Preproc */
+.cpf { color: #75715e } /* Comment.PreprocFile */
+.c1 { color: #75715e } /* Comment.Single */
+.cs { color: #75715e } /* Comment.Special */
+.gd { color: #f92672 } /* Generic.Deleted */
+.ge { font-style: italic } /* Generic.Emph */
+.gi { color: #a6e22e } /* Generic.Inserted */
+.go { color: #66d9ef } /* Generic.Output */
+.gp { color: #f92672; font-weight: bold } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #75715e } /* Generic.Subheading */
+.kc { color: #66d9ef } /* Keyword.Constant */
+.kd { color: #66d9ef } /* Keyword.Declaration */
+.kn { color: #f92672 } /* Keyword.Namespace */
+.kp { color: #66d9ef } /* Keyword.Pseudo */
+.kr { color: #66d9ef } /* Keyword.Reserved */
+.kt { color: #66d9ef } /* Keyword.Type */
+.ld { color: #e6db74 } /* Literal.Date */
+.m { color: #ae81ff } /* Literal.Number */
+.s { color: #e6db74 } /* Literal.String */
+.na { color: #a6e22e } /* Name.Attribute */
+.nb { color: #f8f8f2 } /* Name.Builtin */
+.nc { color: #a6e22e } /* Name.Class */
+.no { color: #66d9ef } /* Name.Constant */
+.nd { color: #a6e22e } /* Name.Decorator */
+.ni { color: #f8f8f2 } /* Name.Entity */
+.ne { color: #a6e22e } /* Name.Exception */
+.nf { color: #a6e22e } /* Name.Function */
+.nl { color: #f8f8f2 } /* Name.Label */
+.nn { color: #f8f8f2 } /* Name.Namespace */
+.nx { color: #a6e22e } /* Name.Other */
+.py { color: #f8f8f2 } /* Name.Property */
+.nt { color: #f92672 } /* Name.Tag */
+.nv { color: #f8f8f2 } /* Name.Variable */
+.ow { color: #f92672 } /* Operator.Word */
+.w { color: #f8f8f2 } /* Text.Whitespace */
+.mb { color: #ae81ff } /* Literal.Number.Bin */
+.mf { color: #ae81ff } /* Literal.Number.Float */
+.mh { color: #ae81ff } /* Literal.Number.Hex */
+.mi { color: #ae81ff } /* Literal.Number.Integer */
+.mo { color: #ae81ff } /* Literal.Number.Oct */
+.sa { color: #e6db74 } /* Literal.String.Affix */
+.sb { color: #e6db74 } /* Literal.String.Backtick */
+.sc { color: #e6db74 } /* Literal.String.Char */
+.dl { color: #e6db74 } /* Literal.String.Delimiter */
+.sd { color: #e6db74 } /* Literal.String.Doc */
+.s2 { color: #e6db74 } /* Literal.String.Double */
+.se { color: #ae81ff } /* Literal.String.Escape */
+.sh { color: #e6db74 } /* Literal.String.Heredoc */
+.si { color: #e6db74 } /* Literal.String.Interpol */
+.sx { color: #e6db74 } /* Literal.String.Other */
+.sr { color: #e6db74 } /* Literal.String.Regex */
+.s1 { color: #e6db74 } /* Literal.String.Single */
+.ss { color: #e6db74 } /* Literal.String.Symbol */
+.bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
+.fm { color: #a6e22e } /* Name.Function.Magic */
+.vc { color: #f8f8f2 } /* Name.Variable.Class */
+.vg { color: #f8f8f2 } /* Name.Variable.Global */
+.vi { color: #f8f8f2 } /* Name.Variable.Instance */
+.vm { color: #f8f8f2 } /* Name.Variable.Magic */
+.il { color: #ae81ff } /* Literal.Number.Integer.Long */
diff --git a/templates/base.html b/templates/base.html
index 4e8b555..e7b538b 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -5,91 +5,12 @@
Bartek Ciszkowski
+
+
-
diff --git a/templates/index.html b/templates/index.html
index b7eda1e..beb761c 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -23,6 +23,7 @@
From d98fe35a57bceb8557650e5dec071afc11e09116 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Mon, 15 Feb 2021 07:02:56 -0400
Subject: [PATCH 04/45] Make code scrollable on mobile
---
pages/golang-context-wg-go-routines.md | 10 +++++-----
static/base.css | 2 ++
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/pages/golang-context-wg-go-routines.md b/pages/golang-context-wg-go-routines.md
index ec1bbee..c8127cf 100644
--- a/pages/golang-context-wg-go-routines.md
+++ b/pages/golang-context-wg-go-routines.md
@@ -78,8 +78,8 @@ When the program is run, we observe the sequence of _"Received job ..."_ message
Received job 5
2021/02/08 21:31:00 Completed doing 6 things.
-The results don't print consistently! This makes sense as we know that go routines
-won't block the lines beneath them unless we do something about it. We can add a
+The results don't print consistently! This makes sense as we know that goroutines are not
+blocking so unless we do somethign about it, code after them will execute immediately. We can add a
`WaitGroup` to improve flow. First, define it in the `var` block:
[sourcecode:go]
@@ -192,10 +192,10 @@ Modify the ticker interval; remove the previous call to `doSomething`, optionall
}
[/sourcecode]
-Run the application and try to exit again. You'll notice two things:
+Run the application and try to exit again.
-* The WaitGroup continues to wait until all go routines are finished. The `doAPICall`
- function blocks until a response is returned from the `httpstat.us` API, and that can
+* The WaitGroup continues to wait until all go routines are finished.
+* The `doAPICall` function blocks until a response is returned from the `httpstat.us` API, and that can
range anywhere from `1000` to `4000` ms.
* Depending on when you try to terminate the application, it can be difficult to do so (you may
not notice this on first pass, run it a few times and try to terminate at different
diff --git a/static/base.css b/static/base.css
index dae28c9..edbfbe4 100644
--- a/static/base.css
+++ b/static/base.css
@@ -80,6 +80,8 @@ article p>img {
/* Customizations for pygments code rendering */
.code {
background-color: #262626;
+ overflow: scroll;
+ -webkit-overflow-scrolling: touch;
}
/* pygments (or Markdown, unsure) adds a at the end of each code block
From a73dff10e4b5700bfc11993c3e13a3229d447118 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Mon, 15 Feb 2021 07:10:15 -0400
Subject: [PATCH 05/45] Don't plaster your name on each page, silly
---
templates/base.html | 4 ++--
templates/page.html | 4 +++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/templates/base.html b/templates/base.html
index e7b538b..1471cdf 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -2,7 +2,7 @@
- Bartek Ciszkowski
+ {% block title %} Bartek Ciszkowski {% endblock %}
@@ -14,7 +14,7 @@
- {% block title %}
+ {% block header %}
I'm a 30-something Polish-Canadian who's lived in many places and visited
+
I'm a 30-something Polish Canadian who's lived in many places and visited
plenty more. Born in Poland, mostly raised in Ontario, and now live in
Halifax, Nova Scotia. Apart from building things, I spend most of my time
- being a father, cooking, travelling, and nerding out over (and advocating for!) public transit
+ being a father, home cook, travelling, and nerding out over (and advocating for!) public transit
A little more about me
-
During the day, I work at Wattpad as a platform engineer. I write Go, support clients interfacing with our platform, and stare at data. Previously,
- I spent many years at G Adventures.
+
During the day, I work at Wattpad as a platform engineer. I write Go, support other engineers, improve processes, and basically make things go. Previously, I spent many years at G Adventures.
In 2020, I realized I hadn't read a novel proper in awhile and decided to get back on track. I now compile what I've read in a virtual book shelf.
In 2020, I set a goal to read 12 books. To many people, that's not much but I hadn't completed a book in awhile (mostly using my reading capacity for online articles). I logged 13, completed 11 of those (or 3,395 pages), and started a couple more.
-
I haven't set a goal in 2021 but continue to dedicate time to reading. We'll see how it goes!
During the day, I work at Wattpad as a platform engineer. I write Go, support other engineers, improve processes, and basically make things go. Previously, I spent many years at G Adventures.
+
During the day, I work at Atolio, where we're fixing the painful process of searching for β and never finding β the information that you know is somewhere within the silos of your organization. Previously, I spent time at Wattpad and many years at G Adventures
In 2020, I realized I hadn't read a novel proper in awhile and decided to get back on track. I now compile what I've read in a virtual book shelf.
From 9b04b4f40127343bf09c07935dca41494e53565f Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Wed, 13 Apr 2022 22:17:20 -0300
Subject: [PATCH 21/45] Update requirements
---
requirements.txt | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/requirements.txt b/requirements.txt
index 89a46fb..1206c34 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
-Flask==1.1.2
-Frozen-Flask==0.15
-Markdown==3.1.1
-pyyaml==5.4.1
-pygments==2.8.0
-Werkzeug==1.0.1
+Flask==2.1.1
+Frozen-Flask==0.18
+Markdown==3.3.6
+pyyaml==6.0
+pygments==2.11.2
+Werkzeug==2.1.1
From 975bb34612d80bbdee8420c6d9a51e2a0b1c0f59 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Thu, 14 Apr 2022 21:03:04 -0300
Subject: [PATCH 22/45] Add This is your mind on plants
---
pages/data/books.json | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/pages/data/books.json b/pages/data/books.json
index 5aae556..67614e2 100644
--- a/pages/data/books.json
+++ b/pages/data/books.json
@@ -230,6 +230,17 @@
"Pages": 208,
"CoverURL": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1372054121l/17707481.jpg",
"GoodreadsURL": "https://www.goodreads.com/book/show/17707481-the-frackers"
+ },
+ {
+ "Title": "This Is Your Mind On Plants",
+ "Date": "2022-04-10",
+ "Subtitle": "",
+ "Author": "Michael Pollan",
+ "Published": "",
+ "Category": "Our World",
+ "Pages": 288,
+ "CoverURL": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1606111590l/56015023._SY475_.jpg",
+ "GoodreadsURL": "https://www.goodreads.com/book/show/56015023-this-is-your-mind-on-plants"
}
]
}
From f845736da1bae62e01a4c018cbef6384e3bda4a8 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Thu, 14 Apr 2022 22:12:26 -0300
Subject: [PATCH 23/45] =?UTF-8?q?Developing=20Wisdom=20=F0=9F=A4=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pages/wisdom.md | 64 ++++++++++++++++++++++++++++++++++++++++++++
templates/index.html | 1 +
2 files changed, 65 insertions(+)
create mode 100644 pages/wisdom.md
diff --git a/pages/wisdom.md b/pages/wisdom.md
new file mode 100644
index 0000000..5dba469
--- /dev/null
+++ b/pages/wisdom.md
@@ -0,0 +1,64 @@
+title: Developing Wisdom
+date: 04-14-2022
+---
+
+I'm still young, naive, and developing. These are the thoughts I'd classify as
+gained wisdom and I imagine most won't change as I grow older (rather, more will
+be added)
+
+
+## Body & Mind
+
+* "Eat food. Not too much. Mostly plants" - Michael Pollan
+* Substances, like caffeine, which are part of daily life should be removed from
+ time to time[^2]. Elimination helps you understand how your body deals without
+ and you have the reward after you've re-introduced (at least, with caffeine)
+* Drink less alcohol, ideally none[^1]. Caution from using alcohol as a
+ suppressant to anxiety in social situations.
+* Prioritize reading over many other activities. Like time in the market (over
+ timing), the long tail benefits outweigh many other things you could do.
+* Read what you like. Can't get into fiction? Don't force it. Enjoy that
+ non-fiction.
+* Prioritize sleep. 8 hours a night, going to bed at least 12 hours since last caffeine
+ intake. This is hard with young kids, but that is temporary. (assume 18
+ months of terrible sleep per child)
+* Approach parenting with your partner as equals. The burdens of parenting
+ belong to both of you, just as much as the joys do. If you're exhausted and not
+ sure how to do this, watch Bluey[^5] with your kids.
+* Have at least one daily practice. This is hard as a parent, but you can fit one thing in. For me in 2020-2022 (and onward) that's been running. 5k a day, 6x a week.
+
+## Family
+
+* Hug, hold, and spend a lot of time with your kids. Around the age of 5-6, they
+ will show more independence. Soon after that, they will want less cuddles,
+ hugs, and time with you.
+* Eat every meal as a family, even when the kids are youngest. This is hard, but
+ worthwhile if possible.
+* Lived experiences are better than a big house, toys, and most things material.
+ Live minimally, experience big.
+* As your family grows, so too will the sparks of new traditions emerge. Try them out and nurture the ones that stick. Traditions, rituals, and ceremony in are an important bonding mechanism.
+
+## Career
+
+* Be kind. Don't gate keep. Follow the Pac-Man Rule[^4]
+* Your career is a pendulum[^3]. Build experiences through multiple avenues.
+ Adjust for life situation, and understand money will always come back. It's ok
+ to take a pay cut today for a healthier tomorrow.
+* Stay at a company long enough to see your projects turn into the company's
+ debt. Understand the implications and short-comings of what you've built.
+* Inversely, leave when you've exhausted your learning and earning.
+* Always obtain equity.
+* There is no template for advice applicable to you. Work through experiences,
+ gain many perspectives, and do your best not to burn out in the process.
+* Save money and leverage the benefits of compound interest. Don't save all your
+ money though; your 20s are for being mostly irresponsible.
+
+## Learning
+
+* If you're watching something at 2x speed, it's not worth watching.
+
+[^1]: https://fergus-mccullough.com/index.php/2021/04/09/against-alcohol/
+[^2]: https://www.theguardian.com/food/2021/jul/06/caffeine-coffee-tea-invisible-addiction-is-it-time-to-give-up
+[^3]: https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/
+[^4]: https://www.ericholscher.com/blog/2017/aug/2/pacman-rule-conferences/
+[^5]: https://www.imdb.com/title/tt7678620/
diff --git a/templates/index.html b/templates/index.html
index 9585220..8e008df 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -15,6 +15,7 @@
From 7f61baad87b4c71dfd74d66234e6407b770d006c Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 10 Jun 2022 07:34:04 -0300
Subject: [PATCH 24/45] Adding a couple of highlights
---
pages/wisdom.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/pages/wisdom.md b/pages/wisdom.md
index 5dba469..c6ec059 100644
--- a/pages/wisdom.md
+++ b/pages/wisdom.md
@@ -56,6 +56,9 @@ be added)
## Learning
* If you're watching something at 2x speed, it's not worth watching.
+* Don't try to figure out what your life is about. It's too big a question. Just
+ figure out what the next three years look like.
+* If you're not sure you can carry it all, take two trips. (apply to most things)
[^1]: https://fergus-mccullough.com/index.php/2021/04/09/against-alcohol/
[^2]: https://www.theguardian.com/food/2021/jul/06/caffeine-coffee-tea-invisible-addiction-is-it-time-to-give-up
From dbc48b0b525f026aff4c9c967c8741a15eba6fb8 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 8 Jul 2022 11:58:43 -0300
Subject: [PATCH 25/45] Add weeknotes, week 1
---
pages/weeknotes-wk1.md | 182 +++++++++++++++++++++++++++++++++++++++++
static/base.css | 4 +-
templates/index.html | 8 ++
3 files changed, 193 insertions(+), 1 deletion(-)
create mode 100644 pages/weeknotes-wk1.md
diff --git a/pages/weeknotes-wk1.md b/pages/weeknotes-wk1.md
new file mode 100644
index 0000000..2786521
--- /dev/null
+++ b/pages/weeknotes-wk1.md
@@ -0,0 +1,182 @@
+title: weeknotes WK1
+date: 07-08-2022
+---
+
+Inspired by other [weeknotes](https://simonwillison.net/tags/weeknotes/) and the
+desire to capture the knowledge, thoughts, questions I encounter each week in a
+place that is not exclusive to me. Week 1!
+
+## Starting things & streaks
+
+For the most part, I feel like a fairly disciplined individual and am well set
+in my routines and habits. But there's lots of things I want to do, with little
+time to fit it in. Trying to mash them in all at once is also difficult and the
+wrong approach.
+
+My oldest has been learning french in school and now that summer is here, I
+thought it'd be fun to continue some of that learning. So, I downloaded
+[Streaks](https://streaksapp.com/) for iOS and am on a 6 day Duolingo streak.
+Nothing impressive, but I'm going to work my way towards some fun vocabulary
+that him and I can share. Upside is that Duolingo Kids is a great product.
+
+Hopefully once I get this as a habit (only 15 min a day of Duolingo!) I can
+follow through with dedicating 30 minutes a day to my
+[Gameboy emulator](https://github.com/bartek/zigboy). A little trickier due to the heavy
+context you need to immerse yourself in, so we'll see.
+
+And yes, I'm using that app to manage my `weeknotes` streak (starting today!)
+
+
+## An introduction to AI-powered semantic search
+
+This
+[video](https://www.youtube.com/watch?v=7ozfzKLTFV4&list=PLq-odUc2x7i8eaYHVXSOadHrVE9tEU2QR)
+was a great introduction into the world of semantic & supervised search, history
+of the tooling, and the shift towards this "new paradigm". As someone who has
+minimal experience in this space, I enjoyed this talk. Notes of interest:
+
+* Traditional keyword search typically used when you have sparse document
+ representations. An inverted index gets you quite far.
+
+* New paradigm and the tooling around it is about retrieving documents using
+ nearest neighbour search. BERT is big here. All the classic tools (like
+ Elastic) are now supporting vector / nearest neighbour search, but not without
+ problems.
+
+* Supervised search is another technique. You need labelled data, and you give
+ the machine those labelled examples. Common trap is to train with an
+ inappropriate data set (flying a car to drive a train).
+
+* [MS Marco](https://microsoft.github.io/msmarco/) is a huge data set from
+ Microsoft (8.8m passages, 500k labelled). Real queries sampled from bing. It's
+ very hard to get *good* labelled data
+
+* When you don't have labelled data, BM25 is a good baseline and starting point.
+
+## Go reflection and custom marshalling
+
+At work, I encountered a fun Go problem where I need to marshal any arbitrary
+struct into a JSON representation that modifies the JSON output at the field
+level, while ensuring only specified fields from the struct are marshalled.
+
+Basically, you go from something like this:
+
+[sourcecode:go]
+type Book struct {
+ Author string `json:"author"`
+ Title string `json:"title"`
+ LastIndexed int `json:"last_indexed"`
+}
+[/sourcecode]
+
+To this:
+
+[sourcecode:json]
+{
+ "author": {
+ "assign": "Kim Stanley Robison",
+ },
+ "title": {
+ "assign": "Red Mars (Trilogy #1)"
+ }
+}
+[/sourcecode]
+
+Note the lack of `last_indexed` in the output. In this case, it is not a
+writeable field. However, we do want it to be marshalled (and unmarshalled) in
+other cases.
+
+At compile time, we know which fields can be assigned this operator (not all
+fields can be marshalled this way). We know the types which we'd like to provide this custom marshalling, and we don't want to overload `MarshalJSON`.
+
+The immediate idea was to implement a custom marshaler, but that overloads the
+JSON tag. Not all fields should be in this output. We could use an auxiliary
+struct though:
+
+[sourcecode:go]
+func (b Book) MarshalJSON() ([]byte, error) {
+ return json.Marshal(&struct{
+ Author string `json:"author"`
+ Title string `json:"title"`
+ }{
+ Author: b.Author,
+ Title: b.Title,
+ })
+}
+[/sourcecode]
+
+This overloads the marshaler which isn't great. We could of course have a
+custom method, `MarshalJSONWritable()`. This works, but it gets cumbersome with
+a lot of fields and many types. Now the behaviour for what is writeable is
+sprinkled in many places, and can be worsened if there's particular behaviour
+we'd need to implement for each marshaler. (I hinted with the `assign` key
+that there may be more than one operator to consider)
+
+So what next? I took inspiration from the `json` tag itself and pondered
+implementing a custom struct tag. Struct tags are small pieces of metadata
+attached to a struct which provides instructions to other parts of your Go code
+as to how it should work with this struct. I can enrich the struct with a custom
+tag, signalling that these are writeable.
+
+[sourcecode:go]
+type Book struct {
+ Author string `json:"author" assign:"author"`
+ Title string `json:"title" assign:"title"`
+ LastIndexed int `json:"last_indexed"`
+}
+[/sourcecode]
+
+I then wrote a simple function which uses reflect to find fields with this tag,
+checking for a few additional traits, like `omitempty`. An example of that,
+snipped for brevity:
+
+
+[sourcecode:go]
+func assignableFields(v any) map[string]any {
+ keys := reflect.TypeOf(v)
+ values := reflect.ValueOf(v)
+
+ assignable := fields{}
+ for i := 0; i < keys.NumField(); i++ {
+ field := keys.Field(i)
+ value := values.Field(i)
+ tag := field.Tag.Get(assignTagName)
+
+ // ... tag checks and omitempty snipped
+
+ assignable[tag] = value.Interface()
+ }
+
+ return assignable
+}
+[/sourcecode]
+
+The output is the assignable fields inside a `map[string]any` which can now be
+marshalled as prescribed by the underlying types. With this, the behaviour around
+the `assign` tag is in a single method (`assignableFields`) and I can package
+all possible operators in one space. There's possibly a bit of digging to
+understand what this `assign` tag is and where its behaviour is defined, but
+that's something I will work through.
+
+I found this solution to be more elegant than auxiliary structs and custom
+marshalling but it might surprise me as it gets primed through use. We'll see!
+
+
+
+## TIL
+
+* Skip index: This came up in a chat about
+ [ClickHouse](https://clickhouse.com/). In a traditional relational database,
+ we create indexes and may create "secondary" indexes to a table to improve
+ query performance, in particular, to reduce the possibility of table scans.
+ ClickHouse isn't 1:1 with relational databases, so they introduce the concept
+ of skip indexes. This different type of index enables ClickHouse to skip
+ reading significant chunks of data that are guaranteed to have no matching
+ values. More
+ [here](https://clickhouse.com/docs/en/guides/improving-query-performance/skipping-indexes/)
+
+
+## End
+
+This was a long weeknotes and it's my first. I'm going to imagine future ones
+will be less ambitious. Either way, this was fun.
diff --git a/static/base.css b/static/base.css
index a553b31..8179416 100644
--- a/static/base.css
+++ b/static/base.css
@@ -105,9 +105,11 @@ p, li {
/* Customizations for pygments code rendering */
+pre {
+ margin: 1rem;
+}
.code {
background-color: #262626;
- overflow: scroll;
-webkit-overflow-scrolling: touch;
}
diff --git a/templates/index.html b/templates/index.html
index 8e008df..b7f3842 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -12,6 +12,14 @@
A little more about me
In 2020, I realized I hadn't read a novel proper in awhile and decided to get back on track. I now compile what I've read in a virtual book shelf.
+
weeknotes
+
an attempt to capture weekly thoughts, learnings, questions
From d475d9e708b9f89e0cdf25ac1260565a1dd70508 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 15 Jul 2022 09:37:17 -0300
Subject: [PATCH 26/45] weeknotes, week 2
---
pages/weeknotes-wk2.md | 55 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 pages/weeknotes-wk2.md
diff --git a/pages/weeknotes-wk2.md b/pages/weeknotes-wk2.md
new file mode 100644
index 0000000..9b5443e
--- /dev/null
+++ b/pages/weeknotes-wk2.md
@@ -0,0 +1,55 @@
+title: weeknotes WK2
+date: 07-15-2022
+---
+
+## Streaks continued
+
+As mentioned last week, I downloaded [Streaks](https://streaksapp.com/) for iOS
+in order to get myself into new habits. These notes and Duolingo specifically.
+
+Duolingo was hit and miss. I streaked for 5 days only to miss a day, then got
+back, and then missed another day. I've been allotting the evening for Duolingo
+time, and I believe that's most appropriate based on my schedule, but the kids
+can be exhausting (our youngest decided to have some bad nights after a few
+very good weeks of sleep)
+
+At least I am here for week two :)
+
+## Go reflection and custom marshalling
+
+As a follow up to [last weeks](../weeknotes-wk1) thinking, the solution I ended up was quite similar
+to what was described. However, I ended up using a dependency! Turns out much of
+what I was attempting to accomplish, which can be summarized by converting an
+arbitrary `any` struct to `map[string]interface{}` in order to further massage
+the data is handled by [github.com/fatih/structs](https://github.com/fatih/structs).
+
+Fatih is well known in the Go community, and although this project is read-only,
+it is stable, well tested, and does more extensively what I was already doing
+with reflect.
+
+Mildly validating to see that others faced such a problem and built tooling to
+support it. The library handles the custom struct tag issue as well, which is
+great!
+
+## Reading
+
+* [Build: An Unorthodox Guide to Making Things Worth Making](https://www.goodreads.com/book/show/59696349-build). I've now been working at a startup for 8 months and the mentality, energy, drive, and potential for burn around the space is really meshing with what I want right now. I'm getting excited about what we're building, but also getting excited to build more myself. The book begins with highlights from the story of [General Magic](https://www.justwatch.com/ca/movie/general-magic), which was one of those mystical (and anti-pattern filled) startups creating something seemingly revolutionary that ultimately, was not a desirable product for anyone but the engineers who were making it.
+
+* [Why is life expectancy in the US lower than in other rich
+ countries?](https://ourworldindata.org/us-life-expectancy-low) was a widely
+ shared blog post from the Our World in Data team. Frustrating to see that many
+ of the most preventable deaths (homicide, opiod overdose, and road accidents)
+ can be preventable with the right supports. Inequality of course, makes a
+ showing.
+
+## TIL
+
+* `Monotonically` is a new word for me. In simplest terms, this means something
+ that goes up or stalls, but never goes down. For example, the number of people
+ born this year is increasing monotonically. Once someone is born, they cannot
+ be unborn. Conversely, world population or birth rates are not monotonic.
+ Although usually going up, it may go down. With [birth rates
+ decreasing](https://ourworldindata.org/grapher/crude-birth-rate), maybe the
+ world population may hit a down slope in the coming decades?
+
+
From 922982757518ae54f1cce1dc96b6535d0d3df79c Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 15 Jul 2022 10:15:19 -0300
Subject: [PATCH 27/45] Add wk2 link; forgot
---
templates/index.html | 1 +
1 file changed, 1 insertion(+)
diff --git a/templates/index.html b/templates/index.html
index b7f3842..c92679a 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -17,6 +17,7 @@
From c28e786db9e01233aced233a7b32114be25ed505 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 22 Jul 2022 11:06:25 -0300
Subject: [PATCH 28/45] weeknotes 3: a short, parenting heavy week.
---
pages/weeknotes-wk3.md | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 pages/weeknotes-wk3.md
diff --git a/pages/weeknotes-wk3.md b/pages/weeknotes-wk3.md
new file mode 100644
index 0000000..1bd457c
--- /dev/null
+++ b/pages/weeknotes-wk3.md
@@ -0,0 +1,38 @@
+title: weeknotes WK3
+date: 07-22-2022
+---
+
+## Parenting
+
+This week has been tough for extracurricular activity. Wife departed for a work
+offsite and thus, I've been parenting solo all week. The result has been days
+focused on keeping the house together and the day job. The minimal downtime I
+had in the evening was used to watch some TV, in this case
+[Yellowjackets](https://www.imdb.com/title/tt11041332/). It's been a surprising
+ride through mystery and supernatural.
+
+There is fun to be had in solo parenting (for short bursts of time). We've
+changed it up each day, went out for ice cream during the week, and had some fun
+mornings & evenings. Keeping it simple.
+
+As a reminder, it takes a village to parent successfully. Build yours (if you
+weren't born into one :-))
+
+## Tracing
+
+At work, I spent some of my time this week wrapping my head around how we should
+implement tracing in one of our applications, with the goal of expanding that
+surface area to further integrations & applications as they come online.
+
+I found O'Reilly's [Distributed Tracing in
+Practice](https://learning.oreilly.com/library/view/distributed-tracing-in/9781492056621/) to be a great introduction and way to develop a fundamental understanding.
+
+As with most things in the instrumentation space, the way to approach your
+particular problem is more art than science, with a heavy lean to the context of
+your use case.
+
+## NYC
+
+Next week I'll be in New York city for my own work offsite. I expect to eat
+great food, run through some interesting neighbourhoods, and spend some quality
+time with my coworkers (who I work with remotely)
From 61c22bcb8ac7e1f03e6a24ae8f150372810941ec Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 29 Jul 2022 21:01:16 -0300
Subject: [PATCH 29/45] wk3 link
---
templates/index.html | 1 +
1 file changed, 1 insertion(+)
diff --git a/templates/index.html b/templates/index.html
index c92679a..1706685 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -18,6 +18,7 @@
From d7fa58cbc7eb3347470b0181da0505c999a8d69a Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Sat, 6 Aug 2022 22:09:29 -0300
Subject: [PATCH 30/45] weeknotes4
---
pages/weeknotes-wk4.md | 29 +++++++++++++++++++++++++++++
templates/index.html | 1 +
2 files changed, 30 insertions(+)
create mode 100644 pages/weeknotes-wk4.md
diff --git a/pages/weeknotes-wk4.md b/pages/weeknotes-wk4.md
new file mode 100644
index 0000000..7e265a0
--- /dev/null
+++ b/pages/weeknotes-wk4.md
@@ -0,0 +1,29 @@
+title: weeknotes WK4
+date: 08-06-2022
+---
+
+I skipped a week of notes! My attempt to form a habit is already slipping.
+However, I had a good excuse: New York city :-)
+
+Spent the week prior in Manhattan with coworkers for an offsite. Met a good
+chunk of the team for the first time (in person), ate some really good food, and
+got to walk the floor of the New York Stock Exchange.
+
+## Summer Hours
+
+Between juggling a busy time at work, I am also enjoying the heck out of summer.
+Somehow we are making it work, and it's mostly because our weekends are spent
+outdoors, generally on a beach. I would say it's exhausting but I struggle to
+use that word for something that genuinely brings me joy (my kids enjoying the
+sun, and well, me too)
+
+## Viewing
+
+* [Prey](https://www.imdb.com/title/tt11866324/) the movie was surprisingly fun
+* [The Bear](https://www.imdb.com/title/tt14452776/) is a show about a
+ dysfunctional Chicago restaurant. Episode 2 has aired and the show is
+ developing well -- keeping an eye on this one.
+* [For All Mankind](https://www.imdb.com/title/tt7772588/). Season 3. What
+ happened?
+
+Not much else to say this week. Lots of work and play.
diff --git a/templates/index.html b/templates/index.html
index 1706685..551fc0d 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -19,6 +19,7 @@
From 0adf195d4ecc87cf402dccceba77365e05c92dfe Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 12 Aug 2022 10:15:12 -0300
Subject: [PATCH 31/45] weeknotes-wk5
---
pages/weeknotes-wk5.md | 36 ++++++++++++++++++++++++++++++++++++
templates/index.html | 1 +
2 files changed, 37 insertions(+)
create mode 100644 pages/weeknotes-wk5.md
diff --git a/pages/weeknotes-wk5.md b/pages/weeknotes-wk5.md
new file mode 100644
index 0000000..85f318b
--- /dev/null
+++ b/pages/weeknotes-wk5.md
@@ -0,0 +1,36 @@
+title: weeknotes WK5
+date: 08-12-2022
+---
+
+## A numerical representation of a piece of information
+
+This week one of my delights was being exposed to the world of
+[embeddings](https://huggingface.co/blog/getting-started-with-embeddings), which
+is a method commonly used in the machine learning space when wanting to capture
+the semantic meaning of what is being embedded.
+
+It is another example of the prominence of vectors in this space and how what is
+ultimately a simple mechanism, can provide great value (when applied
+appropriately). The linked blog post does a good job of running one through a
+query -> FAQ scoring exercise. I did worked through that using a personal data
+set and it was fun. Recommend!
+
+As an aside, I am super impressed with what [Hugging
+Face](https://huggingface.co/) is doing to democratize machine learning stuff.
+The field has felt long-inaccessible, but here is a space with the right
+community, tooling, and guidance to open the door to many more.
+
+## fly.io
+
+I started a side project and chose [fly.io](https://fly.io/) for my deployment.
+I was impressed with the quick startup time. I'll be attempting a project which
+blends a bit of machine learning and live lookups at the edge to provide a
+snappy result. More on what that actually means soon; hoping to sprint on a
+2-week MVP when things calm down with life / work. (do they ever? ... yes)
+
+## Viewing
+
+* [Nope](https://www.imdb.com/title/tt10954984/) I am seeing Jordan Peele's
+ newest flick later today. I appreciate his work because he doesn't hold back,
+ isn't afraid of some in-your-face social commentary, and is a great writer
+ overall.
diff --git a/templates/index.html b/templates/index.html
index 551fc0d..c6c4739 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -20,6 +20,7 @@
From dc8a3c863e770bb10313846e700302f591fad3cb Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 19 Aug 2022 14:56:13 -0300
Subject: [PATCH 33/45] weeknotes-wk6
---
pages/weeknotes-wk6.md | 103 +++++++++++++++++++++++++++++++++++++++++
templates/index.html | 3 ++
2 files changed, 106 insertions(+)
create mode 100644 pages/weeknotes-wk6.md
diff --git a/pages/weeknotes-wk6.md b/pages/weeknotes-wk6.md
new file mode 100644
index 0000000..f8a7f8f
--- /dev/null
+++ b/pages/weeknotes-wk6.md
@@ -0,0 +1,103 @@
+title: weeknotes WK6
+date: 08-18-2022
+---
+
+This week I've had time constraints and what creativity means to me on my
+mind...
+
+## Creative time
+
+Based on my reading and general observations, allotting time to be creative
+(which the definition of is usually subjective to an individual) is one of the more difficult
+things people juggle with. I know I do.
+
+I am grateful that the professional work I do is primarily creative. Developing
+software can be routine and a slog, but I am lucky to be at a place in my career
+where I have choices as to where I wish to work. (which has resulted in me being
+at an early stage startup)
+
+When I was younger, I found my creative time primarily fell in the evenings.
+Fond memories of staying late at my first job hacking away on a Django project
+and driving home at 2am with the windows down. There was no order to it, but it
+could be categorized as time where I was no longer going to be bothered by the
+day's happenings (the boss asking a question, customers, emails, friends/family)
+
+Now with the responsibilities of parental life, I face the challenge every
+other parent has gone through: How do I fit in all these things I want when the
+little kids take up most of my time, have a strict schedule, and are going to
+lose their godamn minds if dinner isn't ready by 5:30pm sharp as it each and
+every day?
+
+The thing with parenting is everyone sucks at it because it's the first time you
+are doing it. When my first kid turned 6, that was the first time I parented a
+six year old. When my second child became a toddler, that was the first time I
+parented a toddler alongside a six year old. Parenting is hard.
+
+So my time for being creative has become constrained, less flexible, and mostly
+falls into very specific time slots. In the grand scheme of things, the
+adjustment is temporary β before I know it, my children will be teenagers and
+I'll have more time than I know what to do with. However, right now, they are
+young. At a high level, my days follow the exact same routine (Ah, there's that
+hedonic treadmill!):
+
+* **5:30am**: Get up and go for a run (5k). This is mostly my preferred approach to
+ starting my day. It works with the exception of times where my toddler gets up
+ early or has a bad night of wake ups (she goes in phases, like most toddlers
+ do)
+
+* **7-9am**: Family time. Breakfast, getting the kids dressed, bit of play, and
+ school / daycare drop off.
+
+* **9am-1pm**: Mostly focused creative time. Usually break for a light lunch or will
+ include a run if I was not able to get it in during the morning. Activity
+ helps to reduce the need for a coffee jolt.
+
+* **1-3pm**: Mostly work meetings. Standups, syncs, etc
+
+* **3-4:30pm'ish**: Wrap up work, maybe knock out a few small things or wrap up what I
+ was doing in the morning. Kids home soon
+
+* **4:30'ish-8pm**: Family time. Play, dinner, more play, bed time routines, clean up,
+ etc.
+
+* **8-10pm**: Attempt to be creative but I'm exhausted so instead usually tinker
+ with a small project, watch TV, play video games, or read a book.
+
+* **10pm**: Sleep because I've been up since 5am and I value my sleep.
+
+As I've grown up as a parent I've done my best to recalculate what I define as
+creative time. This was an important adjustment in thinking, as I found myself
+growing frustrated and anxious with the fact that my creative time was only
+available in such a short window. I dreamed of taking vacation in a small shack
+somewhere away from home just so I could get things done.
+
+It has been a process, but the adjustment has allowed me to see creative time
+differently. When my kids were at their youngest, it was the simplest of things:
+building LEGO structures, leaning block towers to see how high we can go before
+everything collapses. Now as my oldest kid grows up, I see that time spent with
+him much differently. This morning we spent some time making a _black hole space
+cat_ mask (use your imagination) for his day at camp. A few days prior at the
+library, we made a fun scene with Scratch. My toddler, she loves to paint. So we
+go to the backyard and make a bigger mess at her outdoor painting station.
+
+No doubt there are times where I still get anxious about not having that time.
+Sometimes I really just want to get that _one project done_! The desire to run
+away to a shack in the woods exists, but I've learned in order to enable that I
+need to organize my life to allow for a smoother transition into that space. If
+I booked a shack tomorrow for 5 days, I wouldn't know what to do with myself.
+But if I become consistent with taking 30 minutes a day to work on something
+creative (for me, not work) with the intent to build towards something larger?
+Then I have a foundation and can think about that big push. (of course, if I
+leave for 5 days somewhere, the family and my partner need the appropriate
+supports too; not one to just up and leave :-))
+
+But no shack retreat this time. For now, I've come to appreciate the times outside that
+short window of opportunity. Now my creative time shows up in bursts throughout
+the day. It will look different next year and five years from now. As well, if I
+am less anxious and stressed about missing that window of opportunity, I find I
+actually have *more* energy in the evenings, or other opportunistic times to be
+creative solely for myself!
+
+The window to be creative in ways that aren't particular to how I think I want
+to be creative is short, and closes quickly. So for now, I'm going to enjoy what
+I have, be less anxious, and direct my energy more appropriately.
diff --git a/templates/index.html b/templates/index.html
index 4e123b3..db79a64 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -22,6 +22,9 @@
From 5fdfade31d470952ebfcbc32580642e87835e312 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Sat, 27 Aug 2022 20:39:37 -0300
Subject: [PATCH 34/45] WK7
---
pages/weeknotes-wk7.md | 38 ++++++++++++++++++++++++++++++++++++++
templates/index.html | 1 +
2 files changed, 39 insertions(+)
create mode 100644 pages/weeknotes-wk7.md
diff --git a/pages/weeknotes-wk7.md b/pages/weeknotes-wk7.md
new file mode 100644
index 0000000..668e1d1
--- /dev/null
+++ b/pages/weeknotes-wk7.md
@@ -0,0 +1,38 @@
+title: weeknotes WK7
+date: 08-26-2022
+---
+
+## Camping
+
+Summer is winding down and we're fitting in the last visits to the camp ground.
+We've kept it simple this year, exclusively camping at Dollar Lake, Nova Scotia.
+Our final visit for the summer was of the perfect vibe. Evening winding down,
+kids returning from the beach. Running between camp grounds, sharing toys and
+ideas for play. Moms handing out glow sticks and sparklers. Great way to cap off
+another great camping trip.
+
+I have a list from a friend for future, as the youngest one gets to an age
+that's easier to camp with. The list:
+
+* Fundy National Park (New Brunswick)
+* Blomidon
+* Caribou/Munroes Island Provincial Park
+* Kejimkujik National Park (This one's high up on the list)
+* Rissers Beach Provincial Park (Camping on the beach!)
+
+## Bike Map
+
+Through a Twitter thread, a few of us spawned the idea of a bike parking map.
+This maps aims to be a detailed view of bike parking facilities across Halifax
+(and beyond). The detail is street level with labelling of bike racks into
+particular classifications (e.g. Ring, U Ring, Corral, etc)
+
+The goal is for everyone here to have clarity as to how, and if, they can safely
+lock up their bicycle.
+
+I made a repository in which I sync the map
+[here](https://github.com/bartek/hfxbikeparking). The map itself is on
+[Felt.com](https://felt.com/map/Bike-Parking-Halifax-og4BOTBnT3OlCyAVDShLOC?lat=44.652839&lon=-63.613464&zoom=14.654)
+
+I've always had an interest in civic engagement but never pursued, so this is my
+first (small) attempt at such. Let's see what I learn!
diff --git a/templates/index.html b/templates/index.html
index db79a64..ae41fba 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -24,6 +24,7 @@
From 9cd425a176adf097cfa2da62fc7753c0f610e47e Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Sat, 29 Oct 2022 14:08:32 -0300
Subject: [PATCH 35/45] Add some recent books
---
pages/books.jinja2 | 2 +-
pages/data/books.json | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/pages/books.jinja2 b/pages/books.jinja2
index 7013a09..8848402 100644
--- a/pages/books.jinja2
+++ b/pages/books.jinja2
@@ -1,5 +1,5 @@
title: Books I've enjoyed
-date: 01-02-2022
+date: 10-29-2022
data: data/books.json
---
diff --git a/pages/data/books.json b/pages/data/books.json
index 67614e2..8583cbf 100644
--- a/pages/data/books.json
+++ b/pages/data/books.json
@@ -241,6 +241,28 @@
"Pages": 288,
"CoverURL": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1606111590l/56015023._SY475_.jpg",
"GoodreadsURL": "https://www.goodreads.com/book/show/56015023-this-is-your-mind-on-plants"
+ },
+ {
+ "Title": "Build",
+ "Date": "2022-09-10",
+ "Subtitle": "",
+ "Author": "Tony Fadell",
+ "Published": "",
+ "Category": "Startups",
+ "Pages": 380,
+ "CoverURL": "https://images-na.ssl-images-amazon.com/images/S/compressed.photo.goodreads.com/books/1652120231i/59696349.jpg",
+ "GoodreadsURL": "https://www.goodreads.com/book/show/59696349-build"
+ },
+ {
+ "Title": "Conscious",
+ "Date": "2022-10-28",
+ "Subtitle": "",
+ "Author": "Annaka Harris",
+ "Published": "",
+ "Category": "Our World",
+ "Pages": 120,
+ "CoverURL": "https://images-na.ssl-images-amazon.com/images/S/compressed.photo.goodreads.com/books/1551281961i/41571759.jpg",
+ "GoodreadsURL": "https://www.goodreads.com/book/show/41571759-conscious"
}
]
}
From f0dfd73f1a7bff362236b374e06a500cbf166f1c Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 11 Nov 2022 13:16:57 -0400
Subject: [PATCH 36/45] Upload blog to DO droplet
---
.github/workflows/build.yml | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 2874508..929284f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -25,6 +25,20 @@ jobs:
run: |
pip install -r ./requirements.txt
python site.py build
+ - name: Upload to droplet
+ run: |
+ mkdir -p ~/.ssh
+ touch ~/.ssh/id_rsa ~/.ssh/known_hosts
+ chmod 700 ~/.ssh
+ chmod 600 ~/.ssh/id_rsa ~/.ssh/known_hosts
+ echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
+ echo "${{ secrets.SSH_KNOWN_HOSTS }}" > ~/.ssh/known_hosts
+ scp \
+ -o StrictHostKeyChecking=yes \
+ -P ${{ secrets.SSH_PORT }} \
+ -o CheckHostIP=no \
+ -r ./build/* \
+ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.SSH_TARGET_DIR }}
- name: Deploy π
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
From 7f52b09e1cd313602cad9978732c92cc41097e0d Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 11 Nov 2022 13:19:56 -0400
Subject: [PATCH 37/45] bash shell
---
.github/workflows/build.yml | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 929284f..3f1235d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -26,6 +26,7 @@ jobs:
pip install -r ./requirements.txt
python site.py build
- name: Upload to droplet
+ shell: bash
run: |
mkdir -p ~/.ssh
touch ~/.ssh/id_rsa ~/.ssh/known_hosts
@@ -37,11 +38,5 @@ jobs:
-o StrictHostKeyChecking=yes \
-P ${{ secrets.SSH_PORT }} \
-o CheckHostIP=no \
- -r ./build/* \
- ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.SSH_TARGET_DIR }}
- - name: Deploy π
- uses: JamesIves/github-pages-deploy-action@releases/v3
- with:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- BRANCH: gh-pages
- FOLDER: build
+ -r build/* \
+ bartekc@${{ secrets.SSH_HOST }}:/home/bartekc/justbartek.ca
From b34ccdf0ee25994f3b9f3d7bd2ebb794457f468d Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Fri, 25 Nov 2022 10:46:13 -0400
Subject: [PATCH 38/45] Refining my git workflow with --fixup
I like when tools teach me new things, so I wrote my story of past and
current workflow! I think it's also important to highlight that we don't
need to master git, and that learning it over time is perfectly
acceptable.
---
pages/git-fixup.md | 154 +++++++++++++++++++++++++++++++++++++++++++
templates/index.html | 1 +
2 files changed, 155 insertions(+)
create mode 100644 pages/git-fixup.md
diff --git a/pages/git-fixup.md b/pages/git-fixup.md
new file mode 100644
index 0000000..3754c69
--- /dev/null
+++ b/pages/git-fixup.md
@@ -0,0 +1,154 @@
+title: Refining my git workflow with --fixup
+date: 11-25-2022
+---
+
+One of the simplest pleasures of git is it's intuitive enough to use and
+get right at the most primitive level within only a few commit cycles. The other
+pleasures come from learning small tricks which build upon past experience and
+level up your workflow.
+
+Early in my git career, one of the most helpful features to improve flow was
+rebasing. Of course, I was no stranger to *rebase hell* when main was being
+rebased onto a feature branch, but I commonly found myself using `git rebase [-i
+| --interactive ]` as a means of fixing up, squashing, and deleting commits.
+This allowed me to commit earlier, more often, and not worry about quality until
+I had reached my goal.
+
+My initial usage of fixup and squash is perhaps typical, but what I would
+consider messy. Taking a commit log, which has not yet been pushed for review:
+
+ pick 3f0d667 scratch work
+ pick 6add648 added component A
+ pick 8558c32 added component B
+ pick 655324d wired things up
+ pick 7a9c1ce added tests
+
+There was no guarantee each individual commit would build or tests pass. If I
+made a mistake in commit `3f0d667`, it would be resolved in a followup scrappy
+commit. Everything would eventually squash into a single commit, so I had little
+concern for quality of commits. When the work was complete, I'd rebase. It
+consistently looked like so:
+
+ reword 3f0d667 scratch work
+ fixup 6add648 added component A
+ fixup 8558c32 added component B
+ fixup 655324d wired things up
+ fixup 7a9c1ce added tests
+
+Essentially, squashing all commits into a single one and opening my editor to
+rewrite the previously scrappy commit into something more material. It was at
+this point I expected the project to build, all tests to pass, and for the code
+to be submitted for review.
+
+By the book, this isn't optimal, or even correct usage of git. It did enable a
+workflow that was otherwise sufficient for delivering code but it's important to
+regularly challenge your understanding and improve.
+
+## A better commit story with --fixup
+
+In the described workflow, my output resulted in feature branches which
+generally contained a single commit, and I had abstained from creating PRs which
+go beyond a particular cognitive load. If I wanted to tell a broader story,
+I'd chain multiple PRs and branch off branches until the story was complete. It
+was workable but uh, challenging at times (rebase hell, anyone?)
+
+Rigid would be one way to describe this workflow. A single PR could not tell a
+broader story unless I jumped through the aforementioned hoops. I was producing
+what I felt were quality commits, but as time went on, I felt my process
+restrictive. Plus, I was getting tired of branching off branches and keeping
+those organized in the review window.
+
+And then one day, I was introduced to `--fixup`! It's succinctly documented in
+the git manual:
+
+ --fixup=
+ Construct a commit message for use with rebase --autosquash. The commit
+ message will be the subject line from the specified commit with a prefix
+ of "fixup! ". See git-rebase(1) for details.
+
+This made me realize my previous mistakes. Before, I wasn't using fixup
+optimally! It was more akin to a means of squashing all commits into one but
+the benefit comes in being able to *target* a specific commit and well, fix
+it up!
+
+So I began to adapt my workflow. Scrappy commits and experimental branches
+continued to exist and once I made it past this phase I began to construct my
+feature branch with the following principles:
+
+1. Aim to deliver the branch with a series of well written commits. A broad set
+ of rules continue to exist here, which are beyond the scope of this post.
+2. Each individual commit should not go beyond a particular threshold for
+ cognitive load.
+3. Each commit should build, tests pass, and ultimately, be reversible.
+4. Use `--fixup` when I've realized a mistake was made in a previous commit, and
+ let git handle the work of cleaning things up!
+
+I now had more optionality in how I wanted to structure my feature branches and
+eventual Pull Requests. I had to be more deliberate in how I produced work, but
+I also had to worry less about making a mistake in a particular commit. If a
+test was missed, a logical mistake made, or there was a simple linting issue, I
+could `--fixup` the particular commit and not worry about a messy branch for
+eventual review.
+
+Now, when I was preparing a branch for review, my commit log may initially look
+like so:
+
+ 3f0d667 Introduce Component A
+ 6add648 Introduce Component B
+ 8558c32 Wire Up Components
+
+A couple things to resolve, I could target specific commits for fixup:
+
+ git commit --fixup=3f0d667 fixup! Introduce Component A
+ git commit --fixup=8558c32 fixup! Wire Up Components
+
+
+git log then looked like so:
+
+ 3f0d667 Introduce Component A
+ 6add648 Introduce Component B
+ 8558c32 Wire Up Components
+ 655324d fixup! Introduce Component A
+ 7a9c1ce fixup! Wire Up Components
+
+Prior to pushing to an origin for review, I would then rebase `git rebase
+--autosquash HEAD~5`. The fixups would be auto-squashed locally by git and I
+push a feature branch with three commits. I now have a branch with 3 buildable
+commits.
+
+In my Pull Request, I may provide a broader story. In this example about new
+components and wiring things up, I may include a simple architectural diagram (I
+like [Monodraw](https://monodraw.helftone.com/) for this). I use the PR as a
+means of explaining the connections and edges, and each individual commit is
+focused on its own particulars.
+
+Reviewers now get a variety of context. The broader story can be important for
+building context or allowing reviewers to think beyond the scope of the PR
+(*What happens when we introduce Component C?*). Conversely, reviewers may also
+hone-in on a particular commit and not concern themselves with the broader
+picture.
+
+Of course, maintaining a size threshold for PRs is important, but I'm not too
+concerned about the idea of small PRs either. Those reviewing my code may be
+comfortable with the introduced Component A & B, but may not be sure about how
+I've wired things up. The reviewers could step through those commits and
+conditionally approve the PR in that the first two commits could be merged.
+
+Since the commits are clean, buildable, and have passing tests, I could merge
+those and leave a feature branch up containing the final *wire up* commit for
+later review, after we've had our architectural discussion.
+
+And we can see the optionality described. The rigidness in my previous workflow
+has mostly been removed. I can push small feature branches, or larger branches,
+and my reviewers have optionality in how they approve and support merger of
+code. As a writer of code, I worry less about crafting the perfect, single
+commit, because I know I can `--fixup` later. As a team, we build confidence
+because we gain more context in a single PR and don't worry about juggling
+context between multiple Pull Requests which attempt to tell the story.
+
+The beauty of the described is there's few noticeable differences in the prior
+and current, much of it hidden behind the nuance of a refined workflow enabled
+by how beautifully git has been crafted. A great piece of software with a
+minimum barrier to entry which continues to teach over the years I invest into
+it. Lately, I've been refining how I use another new discovery, `git worktree`,
+and I'll dedicate a followup post on how my workflow has been further refined.
diff --git a/templates/index.html b/templates/index.html
index ae41fba..a5b26cf 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -31,6 +31,7 @@
I'm a 30-something Polish Canadian who's lived in many places and visited
- plenty more. Born in Poland, mostly raised in Ontario, and now live in
- Halifax, Nova Scotia. Apart from building things, I spend most of my time
- being a father, home cook, travelling, and nerding out over (and advocating for!) public transit
+
I'm a 30-something Polish Canadian currently residing in Halifax, Nova
+ Scotia (likely my forever home!) with my wife and two kids. I spend most of
+ my time being a father, and otherwise find interest in startups, home
+ cooking, travel, and urbanism.
A little more about me
During the day, I work at Atolio, where we're fixing the painful process of searching for β and never finding β the information that you know is somewhere within the silos of your organization. Previously, I spent time at Wattpad and many years at G Adventures
-
In 2020, I realized I hadn't read a novel proper in awhile and decided to get back on track. I now compile what I've read in a virtual book shelf.
+
I maintain a virtual book
+ shelf to keep track of my reading and in a small way, keep me
+ accountable (to read more)
weeknotes
an attempt to capture weekly thoughts, learnings, questions
diff --git a/templates/page.html b/templates/page.html
index e560cd9..009294d 100644
--- a/templates/page.html
+++ b/templates/page.html
@@ -6,6 +6,8 @@
From b12a7e00fa076b5c6f0a3908e3924cedba0ac7ef Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Sun, 18 Dec 2022 20:39:45 -0400
Subject: [PATCH 41/45] Update actions/setup-python version
---
.github/workflows/build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 3f1235d..b30c58c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -18,7 +18,7 @@ jobs:
restore-keys: |
${{ runner.os }}-pip-
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
python-version: "3.8.6"
- name: Build
From 91444709aa6cc0e54e5a6b5a1b6f19319f4a865a Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Sun, 18 Dec 2022 20:46:19 -0400
Subject: [PATCH 42/45] Use a version of Ubuntu which has Python 3.8.x
---
.github/workflows/build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b30c58c..1c92f88 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -5,7 +5,7 @@ on:
- cron: "0 * * * *"
jobs:
build-and-deploy:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
From cbe88b088031dfa795b4757e1e06fc01c3fa8861 Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Mon, 26 Dec 2022 07:42:12 -0500
Subject: [PATCH 43/45] 1300
---
pages/1300.md | 80 ++++++++++++++++++++++++++++++++++++++++++++
templates/index.html | 1 +
2 files changed, 81 insertions(+)
create mode 100644 pages/1300.md
diff --git a/pages/1300.md b/pages/1300.md
new file mode 100644
index 0000000..f5fc970
--- /dev/null
+++ b/pages/1300.md
@@ -0,0 +1,80 @@
+title: 1,300 kilometres
+date: 12-26-2022
+---
+
+1,300 and then some: the amount of kilometres I ran this year. It is the second
+calendar year in a row in which I've tracked 1,000 or more kilometres, and I
+wanted to take this moment to reflect on what running has done for me.
+
+I didn't become a runner until recently, whatever becoming a "runner" means. I
+spend good money on my shoes, but otherwise run in clothing that's become
+too stretched, too stained, and not appropriate for presentation in society. Most
+runners I've encountered don't dress up much either, but they do love their
+shoes and watches.
+
+I began running in earnest at the onset of the COVID-19 pandemic. No doubt the
+pandemic had been a wake up call to my unhealthy state, which was invisible to
+friends and myself. Most of my problems secured away, hidden behind a fake
+smile, sans the obvious 40lbs of unwanted weight.
+
+Prior to this most recent attempt, I proclaimed running was *boring*! I'd
+prefer to participate in a team sport (Ultimate Frisbee was my choice for many
+years). Gradually, with the growing of our young family, starting anew in the
+maritime city of Halifax, Canada, and being challenged by the ins and outs of
+each week (What crisis you have for us next, world?), finding the time and
+energy to participate in scheduled group activities was ... waning.
+
+Slowly, I learned boring is good. A consistent routine where the only
+expectations were set by myself. This worked exceptionally well during the
+COVID-19 pandemic where my busy & complicated head could have a time of day to
+escape from β¨ everything β¨. These days, the run is a form of daily spring
+cleaning, helping to (re)build the integrity of my body and mind. The crippling
+anxiety slowly reduced, so did the dread. The world continued to throw hard
+balls (at *all of us*), and it was running which helped me not run out of gas.
+It offered me daily strength and re-ignited me in surprising ways. It was what
+I needed for my family but more importantly for myself. For the first time in a
+long time, I believed in myself again.
+
+The run helped solve the daily problem. This may have been as trivial as what's
+going on the dinner table tonight to inter-personal challenges and technical
+problems at work, and so on. I spend the run processing, talking to myself, and
+[listening to others](https://lexfridman.com/podcast/). I step through a
+conversation. Get into my head, and eventually, I come home. Not
+tired, but rested. Today's run is done.
+
+It's not all serious, too! My runs began to include a form of public
+journaling where I engaged with fellow colleagues from the urbanism community
+of Halifax, through updates on city infrastructure, to [mapping bike parking
+across the city](https://github.com/bartek/hfxbikeparking), silly and simple
+things which at times provided me a destination. Through these runs I
+encountered many other runners, sharing peace signs, high fives, and smiles β a
+guaranteed high five coming during the worst of weather, where hardly a
+runner is to be spotted. I can't feel my face but heck yeah, we're out here loving every minute.
+
+β
+
+In late 2021, I encountered a post on [reddit](https://reddit.com) about a
+trail running group called the Halifax Hares. This group runs in wooded trails
+around Halifax and enjoys a 7-9 kilometer run each week, ending the run with
+some cookies and socials (sometimes at a local pub)
+
+Running began as an anti-social activity yet it was clear engagement with
+others was important to me. Running with others has been an adjustment, in
+particular because I am terrible at small talk (thankfully, it's not hard to
+get into interesting conversations over a few kilometres!), and it has been the
+Hares which made this easier. A diverse group of friendly, motivated, and
+inspiring people who are always up to wild things.
+
+Many are ultra runners. Yup, slow (usually trail) running that goes on for 50,
+70, 100km. These runs happen over the course of a day, through the night, and
+challenge every part of the body and mind. I was most inspired by a runner who
+did his first 100km: He ran through day and night within Cape Breton, NS. He
+got deep in his head, was bit by something nasty, and he eventually saw the sun
+rise. Exhausted, fucked up, and happy all at once.
+
+There is a connection here I aim to seek. A connection between the body and
+mind, where the running passes the threshold of physical pain. It is here
+where I anticipate the world can disappear and one in which I will be
+challenged to truly speak to myself.
+
+That is my destination. To get there, I need to run. So, here's to 2023. π
diff --git a/templates/index.html b/templates/index.html
index a648d28..85d0e01 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -33,6 +33,7 @@
From fcae4f8ad08d63a75cbce97b2f2bf2ea638c8c3f Mon Sep 17 00:00:00 2001
From: Bartek Ciszkowski
Date: Sun, 1 Jan 2023 13:39:12 -0400
Subject: [PATCH 44/45] Update total
---
pages/1300.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pages/1300.md b/pages/1300.md
index f5fc970..a553e41 100644
--- a/pages/1300.md
+++ b/pages/1300.md
@@ -2,7 +2,7 @@ title: 1,300 kilometres
date: 12-26-2022
---
-1,300 and then some: the amount of kilometres I ran this year. It is the second
+1,300 and then some (*edit: official tally at exactly 1337km*): the amount of kilometres I ran this year. It is the second
calendar year in a row in which I've tracked 1,000 or more kilometres, and I
wanted to take this moment to reflect on what running has done for me.
From 1aedeafee54f3acec32d8fe65840c3434b2eaac6 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 1 May 2023 23:41:02 +0000
Subject: [PATCH 45/45] Bump flask from 2.1.1 to 2.3.2
Bumps [flask](https://github.com/pallets/flask) from 2.1.1 to 2.3.2.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/2.1.1...2.3.2)
---
updated-dependencies:
- dependency-name: flask
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 1206c34..bdf0e2e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-Flask==2.1.1
+Flask==2.3.2
Frozen-Flask==0.18
Markdown==3.3.6
pyyaml==6.0