SoundCloud 推出的錯誤蒐集工具 Periskop

SoundCloud 推出的錯誤蒐集工具 Periskop,應該是取自捷克文的 Periskop (潛望鏡):「Periskop: Exception Monitoring Service」。

Sentry 這類工具最大的差異在於是走 pull-based 架構,也就是跟 Prometheus 的設計相同 (Prometheus 也是 SoundCloud 發明的專案)。

就資源上來說,當 instance 上的錯誤滿天飛,而超過 log buffer 時,如果是以巨觀的角度來看,其實掉一些東西也沒關係:

另外也有提到一些缺點:

  • If a fatal exception occurs and the process dies, the exception won’t be collected. However, this can be mitigated by the reporting capabilities of orchestration services like Kubernetes or other forms of logging.
  • The pull model is not well suited for short-lived processes like scheduled jobs. This could be solved by the use of a push-based event gateway, although we haven’t yet had the need at SoundCloud, as it is usually more convenient to use logs to inspect failed jobs.

雖然 web (js) 與 mobile devices 的部份沒辦法被這個服務涵蓋,但一般來說會把面向使用者的服務另外拆開,所以不算是缺點... (像 Sentry 那樣通包,主要還是為了商業上的規劃)

目前看起來還缺一些東西 (就我想用的需求),可以先觀察一下會怎麼發展,另外一邊 Sentry 也在朝 Python 3 進行,也可以嘗試看看...

用 TSV 而不用 CSV

最近常常需要提供資料給其他部門 (非技術類的部門),有時候需要提供一些表格類的資料,傳統大多數人比較熟的是產生 CSV 格式的資料讓使用者可以用 Excel 打開,但這個格式其實有很多問題,最常見的就是 encoding 與資料有逗號 comma 的問題。

如果是在 Python 下,其中一個解法是用 openpyxl 直接產生 .xlsx,但用起來還是沒那麼有下面提到的方法順手。

如果是 shell script 時就比較麻煩了,像我這次手上有一堆影片檔,要用 FFmpeg 確認每個影片的 resolution 與 framerate 再提供給同事,這時候如果還是想產生 .xlsx 就累了...

下面要提到的解法好像記得是在 K 社的時候同事教的,用 TSV 檔格式 (當然檔名要取 .tsv),然後 encoding 用 UTF-16 (LE) 就可以解決上面提到的兩個問題,產生出來的檔案可以讓 Excel 直接打開。

StackOverflow 上的「Is it possible to force Excel recognize UTF-8 CSV files automatically?」這邊翻一翻,會發現裡面提到比較好的解法其實都是產生 TSV。

這邊另外推薦,就算是寫程式,也還是可以先產生出 UTF-8 的版本 (通常副檔名我都會先取 .txt),然後用 iconv 或是 piconv 轉成 UTF-16 (LE):

iconv -f utf8 -t utf16le a.txt > a.tsv

包到 Makefile 裡面用起來其實還蠻順手的...

JavaScript 的壓縮器 esbuild

esbuild 是個 JavaScript bundler & minifier,在 GitHub 上的副標提到了重點在於速度:

An extremely fast JavaScript bundler and minifier

從壓縮時間可以看出來優勢:

另外從最終的檔案大小也可以看出來,與最小的 rollup + terser 組合沒有差太多:

實際拿個 jQuery 跑看看,可以看出來壓縮的效果還行:

-rw-r--r-- 1 gslin staff  89228 Feb 19 06:03 jquery-3.4.1-esbuild.min.js
-rw-r--r-- 1 gslin staff 280364 May  2  2019 jquery-3.4.1.js
-rw-r--r-- 1 gslin staff  88145 May  2  2019 jquery-3.4.1.min.js

速度主要是透過 Golang 並且平行化運算達到的:

  • It's written in Go, a language that compiles to native code
  • Parsing, printing, and source map generation are all fully parallelized
  • Everything is done in very few passes without expensive data transformations
  • Code is written with speed in mind, and tries to avoid unnecessary allocations

不過作者有提到這個專案畢竟比較新,還沒有被時間磨練過,可能會有些 bug:

This is a hobby project that I wrote over the 2019-2020 winter break. I believe that it's relatively complete and functional. However, it's brand new code and probably has a lot of bugs. It also hasn't yet been used in production by anyone. Use at your own risk.

可以先放一陣子看看,讓一些先賢先烈把比較大的 bug 踩一踩修一修...

SQL Antipatterns: Avoiding the Pitfalls of Database Programming

標題裡是說這本書:「SQL Antipatterns: Avoiding the Pitfalls of Database Programming」,在 2010 年出版的書。

我是在 Hacker News Daily 上看到「Ask HN: What are some examples of good database schema designs?」這篇,裡面提到了這本書,看了一下章節看到只有 USD$25 就馬上先買起來丟到 Kindle 裡面...

這不是給資料庫初學者看的書,主要的讀者是對於「標準」夠熟 (學校教的那些理論基礎,像是各種 index 的底層結構,正規化的方法,以及正規化的原因),然後也有一些實務經驗後的開發者。

因為裡面把常遇到的問題,與可能的解決方式 (通常都違反當初在學校學的理論基礎) 整理成這本書,在底子還沒打穩前跑來看這本書並不是個好主意...

另外裡面雖然不一定有提到,但有蠻多技巧其實是用在「為了效能而不則手段」的情境下,所以這些內容對於想要調校比較大的網站應該也是很有幫助。

Python 3.7+ 保證 dict 內容的順序

在「Dicts are now ordered, get used to it」這邊看到的,因為 Python 官方 (也就是 CPython) 實做 dict 的方式改變,然後決定把這個特性當作是 social contract,而不是當作 side effect 的特性 (也就是不保證之後版本會有相同特性)。

Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was an implementation detail of CPython from 3.6.

作者裡面的兩張圖清楚表示出來以前的版本怎麼實做,與 3.7+ 的版本怎麼實做:

這樣就很好理解了。

不過考慮到還是有些系統用 Python 3.5 (像是 Ubuntu 16.04 內建的 python3) 與 Python 3.6 (Ubuntu 18.04 內建的 python3,雖然沒問題,但當時還沒有寫出來),也許還是先不要依賴這個行為會比較好。

不過以插入的順序列出好像不是很常用到...

第二堂:「Shell Tools and Scripting」

這個系列是從『MIT 的「The Missing Semester of Your CS Education」』這邊延伸出來的,這篇文章講第二堂課「Shell Tools and Scripting」。

這堂有點像是第一堂的延伸,在講更多 shell 的操作與工具,然後說明 shell script 怎麼寫。

開頭就先說明有 function,然後講了不少 magic variable,像是 $0$1$9,而 $@$# 也提到了 (但居然沒提到 $*),然後再來是 $$!!$_

然後提到 true 與 false,接著就講條件 || 與 && 了。後面就開始講 shell 裡面的 for 與 if,基本上到這邊已經能寫不少東西了?

後面就介紹更多工具...

四個機率問題

在「Some Useful Probability Facts for Systems Programming」這邊看到的四個機率問題,而且都有接近解:

  • 每一次有 \frac{1}{N} 成功的機率,跑 N 次後最少成功一次的機率。
  • N 個球隨機丟到 N 個籃子後有空籃子的機率。
  • N 個數字在隨機排序後有數字不改變位置的機率。
  • N 種 coupon 平均隨機出現,要抽中一套 N 種都有的 coupon 需要抽幾次的期望值。

會想要寫這篇是因為發現最後一題就是「大人買」抽卡問題的簡化版本 (這邊簡化成機率相同,一般的情境下應該是不同的)。

可以看到歐拉常數 e 與自然對數 \ln{} (i.e. 以 e 為底的對數) 滿天飛 XDDD

Python 新的 HTTP client library:HTTPX

看到「A next-generation HTTP client for Python.」這個專案冒出來,宣稱是下一代 Python 的 HTTP client library:

HTTPX is a fully featured HTTP client for Python 3, which provides sync and async APIs, and support for both HTTP/1.1 and HTTP/2.

目前專案還在 beta,目標是在今年四月出 1.0 版。從說明裡面可以看到,目前的方向是打算相容 requests,讓現有的程式可以不用做太多修改就轉移過來。

再來從開發者的角度來看,HTTPX 比 requests 多了這些功能:

  • Standard synchronous interface, but with async support if you need it.
  • HTTP/1.1 and HTTP/2 support.
  • Ability to make requests directly to WSGI applications or ASGI applications.
  • Strict timeouts everywhere.

但如果就支援這些功能的角度來看,修改 requests 看起來應該會比較快?開新的專案感覺跟 Kenneth Reitz 有關...

Kenneth Reitz 有兩個很有名的作品,一個是這個,另外一個是 Pipenv,也就是在「pipenv 的凋零與替代方案 poetry」這邊提到的事情。

然後看了一下 CHANGELOG.md 內的資訊,裡面最早的記錄是 0.6.0 (2019/06/21),而從 Contributors to encode/httpx 這頁看起來則是 2019/03/31 開始發展的,就這些時間點看起來,原因大概跟 Kenneth Reitz 有關... 雖然沒有找到文章直接提到這件事情。

不過 HTTPX 需要 Python 3.6+ 才能跑,對於版本的要求比較高,如果是 16.04 預設的 python3 (3.5) 就沒辦法跑了,18.04 預設的 python3 (3.6) 也才剛好符合...

之後應該是 HTTPX 與 requests 兩邊都得關注了,看看會有什麼發展...

講求速度的 Cryptographic Hash Function:BLAKE3

今年年初發表的 cryptographic hash function,重點在於速度:「The BLAKE3 cryptographic hash function」。

在 1 thread 的情況下就遠遠拉開目前的 cryptographic hash function:

因為速度是主打項目,所以提供的範例已經是使用 x86 與 ARM 的 SIMD 加速的版本,另外也可以透過平行化加速。

所以是要拼 de-facto standard 嗎,不知道 browser 這邊有沒有機會採用,雖然在現在都是使用 AEAD cipher 的情況下好像沒有太多出場機會...