TinyPilot: Month 38

Michael Lynch

TinyPilot:第 38 個月

原文由 Michael Lynch 發布,訂閱此部落格

一句話總結

我在軟體上的投資方向正確嗎?

第一次來嗎?

嗨,我是 Michael。我是一名軟體開發者,也是 TinyPilot 的創辦人,這是一家獨立的電腦硬體公司。我在 2020 年創立了這家公司,目前每月營收約 6 萬至 8 萬美元,並聘雇了另外七位員工。

每個月,我都會像這樣發表一篇回顧,分享事業與整體職涯的近況。

本月亮點

  • 我沒能成功銷售 TinyPilot 授權的訂閱制方案。
  • 我意識到自己把 TinyPilot 做得過度可設定了。
  • 我原本以為自己在 TinyPilot 開發上的投資很不理想,但寫這篇回顧時才發現,大致上仍走在正軌上。

目標成績

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

盡快將生產轉移至代工廠

  • 結果:我很快幫代工廠排除了卡關,但也錯失了一些加速進度的機會。
  • 評分:B-

只要代工廠需要我的回饋而卡住時,我都優先給予快速且完整的回覆,我覺得這方面做得不錯。

我太晚才意識到,自己也應該更主動地管理專案。代工廠有自己的專案經理,所以我以為他們會把事情顧好,但最終,如果進度延誤,損失最大的還是我。

當他們針對包裝盒設計或說明書等事項徵求回饋時,我雖然會馬上回覆,但回完就擱著,直到對方來追蹤才又想起。直到他們準備寄出最終樣品時,我才發現自從上次給回饋後,就再也沒看過包裝盒或說明書的最終定稿。結果設計還需要更多修改,無端造成了延誤。

為搬離 TinyPilot 的實體辦公室制定詳細計畫

  • 結果:我們現在已經有了按月推進、包含目標日期與里程碑的搬遷計畫。
  • 評分:A

我們已經有了計畫,大家對時程也有了共識。

有些想賣掉的設備還是存在先有雞還是先有蛋的問題。比方說,如果先把印表機賣了,要怎麼印出貨標籤來賣其他東西?不過最壞的情況,也不過就是把剩下的東西先搬回家放,再從家裡慢慢賣。

測試 TinyPilot 授權自動續訂的方案

  • 結果:我評估了幾個選項,但沒有一個好用。
  • 評分:B

我本來希望能找到一個 Shopify 應用程式來銷售 TinyPilot Pro 的定期訂閱,但一個合適的都沒找到。詳情請見下文

TinyPilot 數據

指標2023 年 7 月2023 年 8 月變動
不重複訪客7,8006,900-900 (-12%)
銷售營收$79,635.02$91,670.46+$12,035.44 (+15%)
企業訂閱$290.70$290.700
權利金$3,777.52$2,969.62-$807.90 (-21%)
總營收$83,703.24$94,930.78+$11,227.54 (+13%)
獲利$26,359.62$28,454.42+$2,094.80 (+8%)

營收與獲利大致持平。營收比 7 月略有上升,但我認為主要原因是我們在 Amazon 上的商品在 7 月大部分時間被降了排名。

我在訂閱制上的失敗嘗試

上個月,我試著想辦法評估是否值得 更嚴格地執行 TinyPilot 的授權限制。我當時的結論是,最划算的做法是 為授權購買提供自動續訂的選項

Shopify 本身並不支援定期訂閱,所以我得在 50 多個提供此功能的第三方 Shopify 應用程式中尋找。問題是,幾乎所有這類應用都是為實體商品設計的。少數支援數位商品的,又只能在原生的 Shopify 商店上運作,而我的商店 並不是原生架構

題外話:挑選 Shopify 外掛真的是很糟的體驗。很少有外掛提供公開的展示,所以想看它實際怎麼運作,唯一的方法就是真的把它安裝到你的商店裡,並授與它存取所有商品與顧客資料的完整權限。我不願意這麼做,所以改用沒有任何真實顧客資料的測試商店,但很多功能在沒有完整資料的商店裡根本無法運作。結果,因為外掛取得了我真正的 Shopify 電子郵件,現在我還收到一堆來自那些只在測試商店安裝一小時就刪除的應用程式的垃圾郵件。

目前我的選項有:

  1. 完全在 Shopify 之外銷售續訂式訂閱(例如透過 Paddle、LemonSqueezy、Stripe)。
  2. 將 TinyPilot 的購買流程轉換為原生 Shopify 商店,再回頭研究 Shopify 的第三方訂閱應用。

(1)需要開發團隊建置大量基礎設施來支援 Shopify 之外的結帳流程,並確保客服團隊在 Shopify 之外仍能存取顧客資訊。

(2)能讓所有東西都整合在 Shopify 裡,但這也是一項大工程。上次我請人估價,對方報價 2 萬美元。雖然我最終還是想做,因為原生 Shopify 商店還有許多其他好處,但目前我實在沒有餘力處理。

讓 TinyPilot 降低可設定性

TinyPilot 最大的技術債來源之一,就是我們對 Ansible 的使用。當初打造 TinyPilot 時,我還不知道該如何在 Linux 上散佈軟體。我只會用 Ansible,所以 TinyPilot 的安裝程式就是一個極簡的 shell 腳本,先啟動 Ansible,再由 Ansible 完成大部分的安裝工作。

久而久之,很明顯 Ansible 並不是適合這份工作的工具。更細微的錯誤是,我把安裝程式做得太 可設定 了。

在發佈 Ansible roles 時,把作業系統與硬體架構的差異抽象化是很好的實踐。舉例來說,要把一組檔案複製到某個目錄,你不會直接寫「把所有東西安裝到 /opt/whatever」。而是會寫「把所有東西安裝到 {{ my_target_dir }}」,然後在你的 defaults.yml 檔案中定義 my_target_dir: /opt/whatever。這樣一來,如果 FreeBSD 系統想安裝到不同位置,你只要在 FreeBSD 系統上覆寫 my_target_dir,指向類似 /usr/local/whatever 的路徑即可。

但 TinyPilot 只支援一種作業系統與一種硬體平台:Raspberry Pi 4 上的 Debian。

出於習慣,我把路徑、名稱和數值都抽象到不同的檔案中,但這讓我們的程式碼變得更難理解。要搞懂 Ansible 在實際安裝時會如何填入變數,往往得在三個以上的檔案之間跳來跳去。

不可否認,確實有使用者喜歡這種彈性,讓他們能在 我們官方不支援的系統上使用 TinyPilot。但這些使用者幾乎都不是付費用戶,所以我們為了支援這種彈性付出了可觀的成本,卻沒有服務到真正出資支持 TinyPilot 開發的客戶。

最新的 TinyPilot 版本中,我們移除了 Ansible,同時也拿掉了網頁介面以外的大部分設定選項。目前沒有收到任何升級問題的回報,這強烈顯示我們的客戶根本不需要這些可設定性。

TinyPilot 開發工作中的本質與偶然之分

在著名的 〈沒有銀彈〉 一文中,Fred Brooks 將軟體工作分為「本質性困難」與「偶然性困難」。

本質性困難包括定義需求、設計 UI 等。即使你擁有完美的工具與無限的資源,如果沒搞清楚軟體要做什麼、使用者如何與之互動,也無法做出有用的應用程式。

偶然性困難則是那些只因為工具限制而不得不做的事。舉例來說,在 C 語言中管理記憶體,如果我們有自動參照追蹤或無限的記憶體,根本就不需要操心。

最近我時常從這篇文章的角度思考 TinyPilot 的開發工作。我們做的很多事,感覺都屬於偶然性困難。

我把 TinyPilot 上一個衝刺中的任務,分為「本質性困難」(綠色)與「偶然性困難」(紅色):

TinyPilot 2.6.1 版本中的任務,依本質性困難(綠色)與偶然性困難(紅色)標示

有 9 項任務(24%)屬於本質性困難,例如新增或改良功能,而 28 項(76%)屬於偶然性困難,例如修正回歸錯誤、套件更新或重構。

我沒有好方法能以開發時數來衡量工作量,但我猜想,偶然性困難的任務平均來說比本質性困難的任務更耗時。我們可能有多達 90% 的時間都花在偶然性困難上。

我們如何減少偶然性困難?

越深入思考這個分類,我越覺得它不太符合我對 TinyPilot 開發工作的看法。我真正在意的是三個類別,以及我希望投入在各類別上的時間比例:

類別理想投入比例
改善產品70%
自動化與降低複雜度20%
例行維護10%

問題在於這些比例很難平衡。每一行新增的程式碼都會增加維護成本。一個 5 萬行的程式碼庫,所需的維護工作量至少會比 3 千行的程式碼庫多上一個數量級。

誠然,投入 20% 心力來消除複雜度應該能降低維護成本,但不一定能抵消新功能帶來的負擔。去年我們新增了 H.264 視訊支援,為此整合了 Janus,一個第三方 WebRTC 伺服器。WebRTC 極為複雜,光是這個功能就讓我們的維護負擔一夜之間增加了 20% 至 30%。

再想深一點,或許這正是套用我的 50% 法則 的好機會。我們應該把 50% 的時間用於改善產品,接著完成必要的維護,再把剩下的時間投入自動化與降低複雜度。

用這個角度重新檢視上一個版本,我們的狀況是:

類別任務數占比
改善產品822%
自動化與降低複雜度2670%
例行維護38%

TinyPilot 2.6.1 版本中的任務,依改善產品(綠色)、自動化與降低複雜度(藍色)及例行維護(紅色)標示

由於我們大力推動移除 Ansible,比例明顯偏向自動化,但其實比我想像中更接近理想的分配。

透過這三種類別來看,我覺得自己在開發上的投資方向是對的,畢竟在團隊規模不變的情況下,不可能無止盡地擴充功能。

總結

完成了什麼?

學到的教訓

  • 不能永遠只顧著開發新功能。
    • 隨著軟體專案日趨成熟,你要不就得增加開發人員來處理額外的維護,要不就得將重心更多地轉向簡化。
  • 可設定性會帶來隱性的維護成本。
    • 專案中的每個設定選項都會讓行為更難理解,並增加修改的成本。只保留真正需要的可設定選項。
  • 別以為有專案經理,專案就一定會被管得很好。
    • 因為代工廠有自己的專案經理,我就不再去管轉移生產的專案管理。回頭看,我應該更積極地追蹤待辦事項。

下個月的目標

這有點作弊,因為這篇回顧寫得比較晚,所以實際上算是下一週的目標。

  • 盡快將生產轉移至代工廠。
  • 分派清空 TinyPilot 辦公室的相關工作。
  • 把剩下所有的 Raspberry Pi 都用來組裝 TinyPilot 裝置。

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

留言