這邊用 PHP 實作,可以自己改成其他程式語言。
主要是使用 \r
來回到行首,然後使用新的文字蓋過原有的文字,就可以出現簡單的圖形變換效果:
$symbol = ['\\', '|', '/', '-']; $count = 0; echo "\n"; while(1) { echo "\rpending ..." . $symbol[$count % 4] ; $count++; sleep(1); }
不知道有沒有什麼其他符號看起來比較清楚的? O_Oa
軟體開發、伺服器和生活瑣事
這邊用 PHP 實作,可以自己改成其他程式語言。
主要是使用 \r
來回到行首,然後使用新的文字蓋過原有的文字,就可以出現簡單的圖形變換效果:
$symbol = ['\\', '|', '/', '-']; $count = 0; echo "\n"; while(1) { echo "\rpending ..." . $symbol[$count % 4] ; $count++; sleep(1); }
不知道有沒有什麼其他符號看起來比較清楚的? O_Oa
如果是用 python 直接跑:
python3 views.py
Traceback (most recent call last):
File "views.py", line 1, in <module>
from django.shortcuts import render
python 執行了程式,發現 import 或是程式有用到外部 library 而導致噴錯。
python3 -m py_compile views.py
大家都知道把套件裝成 global 會發生什麼事吧?所以若要開發的 project 需要很複雜套件相依性,則可以考慮使用 Python 的 virtualenv。
先來安裝 pip3:
sudo aptitude install python3-pip
在用 pip3 來裝 virtualenv:
pip3 install virtualenv
會後在準備建立的專案執行以下指令:
python3 -m venv project
這個時後你會發現 project 目錄底下已經有不少東西了,這個時候就可以切入虛擬環境中:
$ source bin/activate
(project) $
奇蹟出現了,你的 prompt 最前面已經加上專案名稱,代表你已經完全在專案的環境底下,這環境下不管你用 pip 專什麼東西都不會影響到外部其他專案。
當開發結束,要離開個環境的時候,記得下指令「deactivate」以便離開虛擬環境。
今天剛好要處理 Zip 檔,目前看到功能比較齊全的專案應該是 Ne-Lexa/php-zip,但是用 composer require 時卻發生 error message 大噴發:
仔細一看 …. 居然有「v9.99.99」的版號,該不會要世界末日了吧?
打開 comploser.lock 看一下是怎麼回事,追蹤後得知相依性如下:
laravel v6.10.1 <= ramsey/uuid ^v3.7
ramsey/uuid <= paragonie/random_compat": "^1 | ^2 | 9.99.99"
兇手抓到了,看來在 paragonie/random_compat 有一個版本號是 v9.99.99,composer 會自動拉最新的版本號來使用,因此只要任何專案 require 時沒有指定版本編號,composer 就會自動把相依性對到 v9.99.99,如果其他 package 有關連到,就是直接 dependency conflict 了。
要處理掉這個問題,只要在 composer.json 也 require paragonie/random_compat,但是加上指定版本編號如 ^v2.0,這樣 composer 就只會拉到 v2.x.x 的版本,不會去用 v9.99.99 這個版本。
ref:
若 task 無法立即完成,為了提高 UX,通常不會讓使用者在線上等待 task 完成,而是告知使用者 task 已經在背景執行,完成後再通知使用者。
這個情境下,系統通常是這樣實作:建立一個 queue,將等待處理的 task 全部放進 queue 中,並讓 idle 的 consumer 自動從 queue 中取得一個 task 來執行 (當然也有可能是用 dispatch 的方式)。
假設有 A、B、C 三個使用者的 task 的放進 queue 來處理,一般情況下 queue 的狀態大概會向下面這個樣子:
=> A, C, B, C, A, A, C, A, B, C, B =>
但大多時候工作的分配通常不會這個平均,有時 A 使用者會需要大量處理資料,於是 queue 就會成下面這個樣子:
=> A, C, B, C, A, A, A .... (x1000), A, A, C, A, B, C, B =>
若這個情況下仍然使用相同的 consume 機制,會變成大多數的時間都在處理 A 的 tasks,導致 B、C 使用者的 task 被 (無限) 延後。
在一般狀態下這樣不是一件好事,就像去餐廳買飯,因為前面有個 50 人份的訂單排在你前面,就導致你買一個便當也要等一個多小時。在我自己碰到的狀況,這個時候餐廳通常會有二種作法:
將上面提到的情況改用在 task queue 上,若遇到類似的問題,則可以考慮不同處理 queue 的方法。
例如為不同用途、類型的 task 分別建立不同的 queue,而每次都從個別的 queue 做一次 de-queue,這樣就不會因為 queue-A 大量的 task 卡住其他的 task:
queue for A: t999, t998, t997, ...., t3, t2, t1
queue for B: t3, t2, t1
queue for C: t6, t5, t4, t3, t2, t1
另外也可以考慮使用類似 Laravel API rate limit 的功能,分別記錄每個時段中,各類型的 task 共處理了多少次,若超過限制,則將原本 de-queue 出來準備處理的 task 在 in-queue 輪到較晚處理:
step 1: C, B, A, A, A, A, A, C, A
step 2: C, B, A, A, A, A, A, C
step 3: C, B, A, A, A, A, A
step 4: C, B, A, A, A, A
step 5: C, B, A, A, A // 連續處理二個 A task 了,到達上限
step 6: A, C, B, A, A
step 7: A, A, C, B, A
step 8: A, A, A, C, B
step 8: A, A, A, C
....
當然,用錢可以解決的問題都不是問題。把廚房加個 100 倍大,請一批廚師來炒菜,原本那 50 個訂單就根本沒在怕的啦 XD