TinyPilot: Month 29

Michael Lynch

TinyPilot:第 29 個月

一句話總結

當長期任務停擺時,就該擔心了。

亮點

  • TinyPilot 創下每月 11.2 萬美元的營收,首次突破六位數大關。
  • 我嚴重高估了 TinyPilot 出貨團隊的閒置人力。
  • 長期任務可以是資源即將耗盡的預警指標。

目標成績

每個月月初,我都會宣告本月想達成的目標。以下是本月的達成狀況:

準備將 TinyPilot 的出貨作業轉移至 3PL(第三方物流)供應商

  • 成果:已開始與單一低銷量產品進行導入流程
  • 評分:B

我低估了本地團隊能投入這項工作的閒置人力。再加上銷售額意外暴增,我們未能將內部的出貨流程調整為適用於 3PL 供應商的模式。不過,我們可以先用不完美的流程上路,等 3PL 供應商幫我們釋出時間後再逐步改善。

持續培訓新的技術支援工程師

  • 成果:兩位技術支援工程師已能獨立處理約 80% 的支援工單。
  • 評分:A

技術支援團隊的表現比我預期更出色。除了處理進階的支援需求外,支援工程師還會深入追查問題根源,從源頭減少錯誤發生,並改善 TinyPilot 的診斷日誌。

減少我在關鍵路徑上的專案

  • 成果:我已克制自己不再發起任何新專案。
  • 評分:B

每次推出新的 TinyPilot 機型都需要耗費我大量時間。我已經歷過足夠多次,能預見大部分工作,但我也知道,無論事前規劃多周詳,總會有意料之外的工作冒出來。即使有些日子感覺自己還有餘裕,我仍盡量讓自己的時間保持空檔。

TinyPilot 統計數據

指標2022 年 10 月2022 年 11 月變化
獨立訪客7,9949,512+1,518 (+19%)
總瀏覽量17,86220,387+2,525 (+14%)
銷售營收$85,834.20$107,223.10+$21,388.90 (+25%)
企業訂閱$290.70$290.700
版稅$5,544.12$4,402.50-$1,141.62 (-21%)
總營收$91,669.02$111,916.30+$20,247.28 (+22%)
利潤$26,042.39$7,407.30-$18,635.09 (-72%)

TinyPilot 再度創下銷售新高,總營收達到 11.2 萬美元。這是 TinyPilot 有史以來首次單月突破六位數。

這次成長主要歸功於 TinyPilot 在 Linus Tech Tips 上獲得正面提及,這是深受 homelab(自架實驗室)愛好者歡迎的熱門 YouTube 頻道之一。儘管該支影片主要是在介紹競爭對手的產品,但由於該頻道訂閱人數眾多,TinyPilot 在接下來兩週內仍迎來了可觀的訂單激增。

我很欣慰看到三個月滾動利潤即使在成本異常偏高的情況下,仍穩健地維持正值。TinyPilot 目前正以較高成本透過 3D 列印來生產超出常規產能的外殼,但等到一月改用金屬外殼後,成本應該會大幅下降。

我們沒有足夠的時間來為自己節省時間

十一月的目標之一是開始將訂單履行轉移至 3PL 供應商。我請出貨團隊的一位成員檢視我們的工作流程,並準備將其移交給 3PL 供應商。

隔週,我們因 Linus Tech Tips 的影片迎來訂單暴增,因此轉移至 3PL 的研究工作毫無進展。又過了兩週,我們仍在消化暴增的銷售量,同樣沒有任何進一步進展。

下次與出貨團隊成員會面時,我問他平常處理這類非常態任務有多少餘裕,結果令我驚訝的是,答案大概是零。出貨團隊光是處理組裝裝置、出貨以及回覆支援請求等短期任務,就已經佔滿了一週的所有工時。

這種情況我並不陌生,只不過通常處於沒有短期餘裕狀態的人是我。

任何工作流程通常都有顯而易見的省時方法。可能是自動化、增聘人手、改用代管服務等等。但問題在於,改變工作流程本身就有摩擦成本。

過去幾個月,我一直在畫漂亮的 圖表,來說明委外與授權分工所需的時間投入。秉持同樣的精神,以下是我在聘人接手某項任務前後所投入的時間:

圖表顯示在面試與培訓新人的過程中時間投入增加,之後隨著對方接手任務而逐漸減少。

一開始,這項任務很耗時,因為所有工作都由我親自完成。當我聘請他人時,工作量反而更大,因為除了原本的任務外,我還要投入招募與培訓新人的工作。當新人完全上手後,我才能真正獲得淨節省的時間,但依任務複雜度不同,這可能需要數週甚至數月。

實際上,一天只有這麼多小時。如果把工時上限納入考量,會發生什麼事呢?

圖表顯示考量每日工時上限後,因沒有足夠的短期餘裕來聘僱與培訓新人,導致無法完成交接。

糟了,現在我因為短期內沒有餘裕去聘僱與培訓新人,反而無法達到聘僱後的狀態。我沒有足夠的時間來為自己節省時間。

將長期任務作為耗竭的早期警訊

轉移至 3PL 供應商的延遲,讓我意識到我需要一套更好的機制,來及早察覺閒置產能何時會耗盡。

我目前最好的想法是,更審慎地平衡每個人的短期與長期任務。舉例來說,支援工程師最緊急的職責是在 TinyPilot 支援論壇和我們的 CRM 平台上回覆客戶支援請求。支援量的高低起伏不定,因此當支援工程師有空檔時,他們會尋找支援請求中的重複模式,並發布說明文章或深入追查更根本的錯誤修正。

TinyPilot 的每個人都同時肩負短期與長期任務:

團隊短期任務長期任務
創辦人團隊管理
供應商管理
工作審核
填補職責空缺
行銷
對外撰文
重新評估策略
招募與培訓
出貨人員組裝裝置
訂單履行
客戶服務
建立客戶支援操作手冊
協助行銷
技術支援工程師回覆技術支援問題撰寫文件
撰寫部落格文章
追查棘手的錯誤
軟體開發人員發布新功能
修正緊急錯誤
重構程式碼
改善開發體驗
建立自動化測試
修正非緊急錯誤

長期任務可以扮演礦坑裡金絲雀的角色。當某個團隊在長期任務上的進展持續放緩,就代表他們很可能已接近產能上限。這時,我就應該設法透過減少職責或增加人力來降低負荷。

以長期任務作為警訊有兩個挑戰。第一個是,最常忽略長期任務的團隊就是創辦人團隊,也就是我自己。當我負荷過重時,我不會察覺其他團隊在長期任務上的進展放緩。即使察覺了,我也沒有時間採取行動。我想,解方是對自己承接的專案數量保持更高度的警覺,以便為流程轉換成本保留餘裕。

另一個問題是,出貨團隊最缺乏明確的長期任務。我們的製造與出貨流程並不是那種每週都能持續改善的工作流程。但隨著我們將出貨與製造轉移給第三方供應商,出貨團隊的職責將轉向客戶支援。客戶支援在回覆支援請求的短期工作與完善內部操作手冊的長期工作之間,有著更自然的平衡。

跳脫 Ansible 的坑

Ansible 是一套用來自動化設定伺服器的工具。我已經用了七年,所有自架實驗室中的虛擬機器都是靠它來管理。

早在 2020 年開始開發 TinyPilot 時,我需要一種方法將程式碼部署到 Raspberry Pi 上,並設定 TinyPilot 所需的作業系統功能。由於遠端系統設定正是 Ansible 的強項,它成了合適的選擇。

當我發布 TinyPilot 時,對我而言最簡單的安裝方式,就是複製我在開發時使用的工作流程。我建立了一個簡易的安裝指令碼,先引導建立 Ansible 環境,再透過 Ansible 安裝 TinyPilot。

當時我就知道,更正規的安裝方式應該是使用 Debian 套件。問題是,我對製作 Debian 套件一無所知,而且看起來很費工。我需要自己架設 apt 套件庫嗎?需要管理套件庫的金鑰嗎?TinyPilot 依賴 nginx,那我該如何從自己的套件中去設定 nginx?

兩年半後,開發團隊正為我當初選擇 Ansible 付出代價。隨著 TinyPilot 功能越來越多,我們的 Ansible 設定變得極其複雜。如果安裝程式是純粹的 shell 指令碼或 Debian 套件,安裝過程大概只要 10 到 20 秒。但 Ansible 帶來的額外負擔,卻讓安裝與更新時間拉長到六分鐘以上。

除了對終端使用者的影響外,Ansible 也往往會吞噬開發資源。Ansible 程式碼的除錯既緩慢又繁瑣,尤其是在處理持續整合環境中無法取得的作業系統與架構時。小小的更動經常會膨脹成一週的開發時間。

過去幾個月,開發團隊一直在探索如何將 Ansible 程式碼移植到 TinyPilot 的 Debian 套件中。我很高興地說,我們現在已經有了初步成果。我們建立了一個混合式解法:讓 TinyPilot 的 Ansible 角色去安裝最新的 TinyPilot Debian 套件。這讓我們能逐步拆解 Ansible 程式碼,並一點一滴地搬移到 Debian 套件中。

以下是我希望當初開始開發 TinyPilot 時就知道的 Debian 相關知識:

  • 不需要架設自己的 apt 套件庫,也能建立並散布獨立的 Debian 套件。
  • 只要照著正確的教學操作,建立一個簡單的 Debian 套件只要 15 分鐘。
  • 可以使用 Docker QEMU在 x64 系統上建置 ARM 架構的 Debian 套件。
  • 如果你的程式碼是用 Python 這類可攜式語言撰寫的,甚至可以跳過 QEMU,直接建置與架構無關的 Debian 套件。
  • 若你的套件需要設定另一個套件,標準做法是在設定目錄中新增一個檔案,而不是去修改對方套件擁有的檔案。
    • 例如,TinyPilot 的 Debian 套件可以透過在 /etc/nginx/sites-enabled/ 目錄中新增檔案來設定 nginx。

學習 Debian 最困難的部分,是在眾多雜訊中找出有用的資訊。很多資源基本上都說:「去讀長達 9,000 頁的 Debian 維護者指南就對了,但請忽略其中過時的部分。」

我覺得最有幫助的指南是:

Vincent(文森·貝爾納)甚至還熱心地與我進行視訊通話,解答我對 Debian 套件的剩餘疑問。

業餘專案

ScreenJournal

我看了很多電視節目和電影,也很喜歡向朋友推薦,但我常常忘記自己想推薦哪一部。

我四處找過有沒有像 Goodreads 追蹤閱讀那樣、可以追蹤電影與影集的應用程式,但沒有一個符合我的想像。我覺得朋友們已經對預設公開的社群應用程式感到厭倦,所以我想要一個能讓一小群朋友分享推薦的東西。比較像 Discord,而不是 Twitter。

我已經開始開發一個與朋友分享影評的應用程式。它叫做 ScreenJournal

ScreenJournal 上我的影評截圖

ScreenJournal 就像專為沙發馬鈴薯設計的 Goodreads。

它還沒完全準備好上線,因為目前的評論是私密的,而且只支援單一使用者。現在,它只能作為一個人的私人電影日誌發揮作用,不過我的待辦清單下一項就是支援多使用者。

使用者管理向來很難做到完善,所以我一向避免自己動手實作。過去幾年,我一直使用朋友 David Toth(大衛·托斯)的 UserKit 服務來管理使用者。UserKit 一直表現得很棒,但它尚未對外公開,這讓想在自己伺服器上運行 ScreenJournal 的其他開發者難以使用。

我曾尋找適用於 Go 的開源使用者管理框架,但大多數都依賴來自外部服務的 OAuth,這不是我想要的。其餘的則過於笨重複雜,讓我不想費心。

所以,我正冒險自己來做使用者管理。在工作階段管理上,我使用 jeff,而在驗證上,我打算使用 bcrypt,然後聽天由命。

總結

完成了什麼?

  • 已開始與 3PL 供應商的導入流程。
  • 在幾個重要面向改善了 TinyPilot 的 Debian 套件。
  • 為國際承包商找到了更好的付款平台。
    • Deel 的體驗很差,我對 Remote.com 也不太滿意,所以我們決定採用 Pilot

學到的教訓

  • 長期任務是資源耗竭的良好領先指標。
    • 若團隊在長期任務上的進展持續放緩,就必須在失去調整流程的喘息空間前及早處理。
    • 創辦人更需為長期任務保留時間,否則就無法有效應對其他團隊的資源耗竭。
  • Debian 套件打包並沒有一開始想像的那麼令人畏懼。

下個月的目標

  • 完成來自 3PL 供應商的第一筆訂單出貨。
  • 完成下一個 TinyPilot Pro 版本的程式碼。
  • 為一月推出 TinyPilot Voyager 2a 做準備。

原文由 Michael Lynch 發布

本文章由 muse-spark-1.2-contributor 進行翻譯