3/22
修好 new printing 讓他可以用
取代(? papercut
by PM 大大 willychan: 好好寫後端跟 test 確定他不會出大問題,可能要做到什麼當 DB 掛掉要自動切到備用 DB 之類的
先不管,、做出可以動的東西再說
界面應該仿製 papercut
API
登入:使用者輸入帳號密碼驗證
要傳的 json:
json {status: string, cookie: string, error_reason: string}
(後端)可能需要 LDAP 給一個 API 做驗證(?
password
query user 餘額
直接檢查 cookie session ?
上傳檔案並列印
檢查餘額(?
上傳多個檔案
單/雙面列印
不檢查格式,等列印結果有問題再報錯
讓 UI/UX 可以 query status
GET
[ ] ubuntu 裡面開一個小的 windows vm 負責列印
ubuntu backend -> windows VM -> modify driver info -> print
工作分配
陳陽天:ubuntu backend: 處理跟 UI/UX 對接、LDAP 驗證
尤薪綸:ubuntu backend: 跟 windows VM 對接
張秉中:很多個(? windows VM :修改 driver info 讓他可以列印,並且要取得列印結果回傳,可能會需要用到密碼明文
先不管,去問 wiwi papercut 怎麼做到的
ubuntu 跟 windows 之間 接一個 RSA?
或者是再 windows VM 裡面 query user 的 password 明文
TODO
定開會時間?這週先不開會,這週先搞清楚狀況下週再開會
叫 willychan 多開幾個語音頻道給各組用
3/23 with UI/UX
他們會實作的頁面
登入
上傳 pdf
看目前那份文件的 status
3/30 會議
UI/UX 對接:高翊恩
進度報告
[https://hackmd.io/@uuuu2024/Sy5Jhy_jex](ubuntu 後端 -> windows)
把 windows 的自動化研究好了,可以用 auto hot key 跟 summatra pdf 做到從 cli 做事 -> 剩接到 server.py 上
Django 與 pypdf API
給出 前端的 API 細節
TODO
還要處理 job queue 從 windows 到 ubuntu 的 API 要回傳什麼(或 ubuntu 要給我什麼?)
好欸 ubuntu 後端可以用 pypdf 把 pdf 先接起來,windows 那邊不用處理 XD
windows 那邊先當作只上傳單一檔案
By wiwi 的列印流程(new printing)
(前端 -> 後端帳戶驗證)-> windows 印表機 -> new printing server (需要 jump.csie.ntu.edu.tw 才可存取) 驗證餘額等等 -> 通過之後到印表機
TODO: API 細項
https://hackmd.io/@uuuu2024/Sy5Jhy_jex
API
登入(GET/POST “接口?”):使用者輸入帳號密碼驗證
要傳的 json:
json {status: string, cookie: string, error_reason: string}
(後端)可能需要 LDAP 給一個 API 做驗證(?
password
query user 餘額
直接檢查 cookie session ?
上傳檔案並列印
檢查餘額(?
上傳多個檔案
單/雙面列印
不檢查格式,等列印結果有問題再報錯
讓 UI/UX 可以 query status
GET
下週挪到週三 16:00 ~17:00?
之後還要幹嘛?
張秉中趕快給出後端需要的東西,這樣中間才可以做事
4/8(? 會議
ubuntu 後端對接 windows: 每個 job 用一個 int 表示,windows 只負則處理列印部份(需要 windows VM 才能做的事情們),剩下紀錄用戶/餘額查詢都在 ubuntu 做?
目前 Ariel 的身份驗證是爛的 QAQ 基本上帳密亂打都會過
更:wiwi 修好了
Windows 目前回傳 printed 的意思其實是 submit 給印表機了,並不代表已經印好了(驗證沒過也會回傳 printed,所以印表機回傳不太可信)
前端工作:
LDAP 出來了可以去接身份驗證了
餘額的部份張秉中會去找 NASA 借 jump.csie.ntu.edu.tw 到 new printing server 看看怎麼辦
前端大致上高翊恩寫完了 >w< ,應該剩下把網頁跟後端接起來等等的工作
ubuntu 到 windows:
目前有的功能只有測過列印而已,但是應該要有 query 工作們的功能(?可能會再需要幾個 grpc 的接口去處理
總之 jobs 查詢的 code 只需要接口就可以了
API 流程清單
列印:前端 -> ubuntu -> windows (回傳 job id(int) ubuntu)
餘額:前端 -> ubuntu -> new printing server
登入驗證:前端 -> ubuntu -> LDAP server
查詢列印進度(列印完應該會 redirect 過來):前端 -> ubuntu -> windows (用 job id 查)
TODO
ubuntu -> sender
把 grpc 包成 python library 讓 django server 去 call
ubuntu -> ldap
ubuntu -> 前端
ubuntu -> new printer server
把 ubuntu 用 VPN 關到 jump.csie 中
ubuntu -> windows
Jobs(整個清單)
先不做單一 user 做整個清單,到時候要的話再改
Job(單一工作)
給 windows 一個 job id ,回傳是否 printed
Deadline
4/18 以前把 grpc 接好、windows 把 jobs 的查詢 API 弄好
4/19 前完全做完
Demo 目標
login
單一檔案,可以選單雙面
開會時間
改成週三下午 16:00~17:00
4/15 進度追蹤
Windows server
改成不驗證身份了,因為餘額系統接不出來所以目前直接在 ubuntu 架一個餘額的 server 測試(目前是用 superuser 過)
所以在 ubuntu 裡面有蓋好測試用的 sqlite3 了,應該 import 一下就可以用了
TODO
方案 1 :總之可能改成一定得過前端?拔掉直接戳印表機的方法
方案 2 :想辦法 reverse/生出跟 new printing server 同步的方式(用bs4 直接戳會需要戳 $10^4$ 頁的 UI 找人,不然就是要找出 db 在哪裡戳他)
TODO
Gprc TODO
windows server query job
testing
UIUX Backend
接 LDAP
接 grpc 到 windows
接 database 餘額
Windows
latency:主要的延遲來源其實是 sumantrapdf.exe 執行時間,之後換個方法試試看(應該不會影響到其他前端運作)
進度規劃
趕進度
如果接前端 web 來不及,就改成 DEMO 直接 curl ubuntu
確認東西可以從
uiux_backend/這層 import (不然到時候還要修會很麻煩
4/29
工作整理與分配
基本功能
Windows 後端 (by 張秉中)
把 sumatrapdf 換掉(問題:winget 抓的東西不知道到哪裡了)
Ubuntu 後端
GET /api/print 會拿到 username 跟餘額
改名叫 /api/me
餘額系統換一下可以 concurrent 的,用 sqlite 太蠢了(by 張秉中)
餘額系統可能換成 postgresql
增加上傳多個 pdf 的功能(by 陳陽天)
Pdf 切割合併
增加 /api/jobs/my 的功能(by 陳陽天)
會需要新增一個 database 儲存 printing submissions
django API
admin(by 陳陽天)
修改 DB 餘額資料:django 那裡要驗證身份
也需要 database 紀錄 admin 身份
前端(by 高翊恩)
修好前端 username 只會顯示 miku 的問題
需要多寫一個 /jobs/my 的頁面,顯示那個人自己的 submission(先不做動態更新,手動刷新就好)
可以寫一個 /admin 的界面可以看到 users,還有查用戶餘額
可能會需要 /admin/users 跟 /admin/jobs
查特定使用者並修改餘額
nginx (by 張秉中)
把 reverse proxy 接好,
newprinting.org/接到前端
HA
碰到 HA 要小心 race condition
Ubuntu 後端
用 gunicorn 包起來,在後端開兩三個 instance(尤薪綸)
問題:session 跨 instance 會失效
蓋一個 redis db 給他們 cache?
問題:餘額系統 race condition?(by 張秉中)
寫的時候要注意用 postgresql 的 atomic operations
跟 windows 對接(尤薪綸)
用多個 grpc 對接 windows server(s)
JobID 要改用其他方法儲存,像是
IP_port_jobid怎麼隨便選 grpc ?
查 job 狀態除非該 job 不是 in queue 不然直接問 DB 就好
每天低峰時間(早上 4:00 之類的)跟所有 windows server sync
Windows 後端
好解決,直接多個 grpc server (
python3 server.py {port} {printer_name})PrinterUtils.py: 張秉中
server.py :尤薪綸
多個 driver 應該已經解決了
Nginx(by 張秉中)
設定要改,盡量讓同一個 IP 來的 client 接到同一個 api
load balancing 要開
可能不重要
containerize
死線
HA 跟基本功能開 branch 做事
DSA 軟工死線:三週後(?
OS mp3:5/11
5/6 開會
記得寫測試
關於 HA
PDFtoPrinter 裝好了,但感覺效果沒有好多少
宣告死亡
其實是要做讓東西倒掉之後還可以動
但目前的架構應該是好的,因為這樣我們機器可以倒很多臺才會出事
gRPC 改成 single thread ,跟印表機 driver 一對一
printerUtils 可能會稍微改一下接口,會用一個 class 包起來
(張秉中)改
submit_print_job_bytes()
TODO after 機率小考
Testing
Django (陳陽天)
接到 Redis DB
Docker
傳多個檔案
寫 api/jobs/my 查自己的 submission
Django Log
查 admin/新增 admin(張秉中)
跟 Scheduler 對接的 gRPC(尤薪綸)
DB(張秉中)
HA
蓋 Table
Scheduler(尤薪綸)
開兩個服務
print
往後送到 windows 的 print port
query
往後送到 windows 的 query port
更新 DB 中的 submission
DB
Redis
Postgres
balance (蓋好了)
admin
username
submission
uid: string
wid: string
status: string
time: string
pages: int
Nginx
需要 Django 做完 Docker ?
5/13
新的流程(refund):
scheduler 如果送到windows失敗,他會retry最多3次,如果還是失敗
scheduler去submission table把status改成failed且附上reason(string)
scheduler會去call django的refund服務並傳入id1,再交給django去查balance db、update balance db(把錢加回去)
django去寫一筆transaction_log紀錄
新的流程(to django)
需要django先去db submission table新增一個類似skeleton的東西(wid還不能填入),然後先把status(新的field)設為pending
用grpc傳給scheduler,scheduler這時候是grpc server
scheduler有一個獨立的single worker thread,他會去卡在conditional variable上,平常sleep wait for pending submission
event(pending submission) occur的時候會醒來
另外他定期5分鐘會期來scan db submission table,確保沒有因為grpc失敗產生的orphan pending submission
TODO
DB(張秉中)
開始做 HA
redis 的 sentinel 應該好了
postgres 可能用 master/slave 備份
開 transaction table 跟改一下 submission table
Django(陳陽天)
接 redis DB
Docker
加 /api/refund
跟 scheduler 對接(陳陽天跟尤薪綸自己接起來)
api/jobs/my
Scheduler
給出讓 django 戳的 api
FE
測試前端能不能動
5/20 Meeting
下週之前的 TODO
DB(張秉中)
要兩台 VM 之後做 postgres HA
改一下 submission table
加 money 欄位在 np_submission
Django(尤薪綸)
加 /api/refund
跟 scheduler 對接(陳陽天跟尤薪綸自己接起來)
api/jobs/my
給出讓 django 戳的 api
Docker
研究 CUPS(陳陽天)
跟 hardware 組處理 logging
5/27 Meeting
TODO
週五前:/api/submissions/(張秉中) 週六前: scheduler->windows(尤薪綸) 週日前:containerize(陳陽天)
Document
架構圖

從 nginx 開始左到右依序為 nginx, django, scheduler, DB, windows server, Printer
Nginx
使用 newprinting.csie.org 做 domain name
做 load balancing 將多個前端 request 分派給多台 django 去處理
在做 load balancing 的同時去監控是否有後端死亡,有的話要重啟
將
location /, location /assets等等 forward 到前端將
location /api, /static等等後端物品 forward 到後端(這部份會需要做 load balancing)
Django
接收後端 request
/api/login:直接在 django 處理之後回傳
/api/me:去 DB 的 balance table 查詢餘額之後回傳(用 cookie 檢查)
/api/admin:去 DB 的 admin table 檢查
/api/jobs/my:對 scheduler 發送 print query 查詢對應 user 的工作(via gRPC)
/api/print:先用 pypdf 數頁數並扣款之後,將對應的多個 file 在 django 用 pypdf 將檔案合併成一個之後傳送一個 print request 給 scheduler ,並等待 scheduler 回傳一個 job ID(via gRPC)
由於會開啟多個 django instance ,因此為了讓使用者的 session 可以共享(不同 django 的 session 不一定可共用),需要開啟一個 redis DB 來將所有的 cookie 紀錄,並統一到 redis 查詢
Redis
redis 部份應該會用 sentinel 進行,但是因為目前全部用 docker 做所以 docker-compose 設定要修改,不能讓他直接給 django domain name 而是要給 localhost:port
Scheduler
主要功能為降低送 request 到印表機的延遲,並把那部份變為 async
紀錄一個 printing queue 並依序發送給 windows server
在發送的同時先回應 django server 一個 id1,也就是 django 端認知到的 jobID
每一個 print job 會是一個 jobid pairt (id1, id2),其中 id1 是 django 端認為的 ID ,而 id2 則是 scheduler 跟 windows 端查詢用的 id
這樣設計的主因是因為 id2 只有在經過 windows server 送出 printer request 之後才可以取得,因此在 async 的情況下前端會需要一個暫時的 id
收到 print job 的 workflow
取得一個 id1
將 (id1, -1, time.now())放進 DB 中
將工作放進 print queue
回傳 id1 到 django
收到 get print job 的 workflow
在 DB 中 query id1 或 user
如果 id2 = -1 ,那就 return “pending”
如果 id2 != -1
如果 status=in queue 或 pending 就往 windows server query status
否則直接回傳 status
透過 gRPC 接收來自 django 的各個 request ,並且將需要到 windows server 的 request 用 gRPC 送出
DB
基本上就是一個 postgres DB,table 有 balance, admin, submissions
Balance
由於在 django 驗證過身份了,所以到這裡的 user 一定都是合法 user
如果 user 不存在,就建立新 entry 並初始化餘額
如果 user 存在就直接查詢餘額
(username: string, balance: int)
只會由 django 存取
Admin
只需要存 admin usernames
(username: string)
只會由 django 存取
Submissions
紀錄所有列印 submission
只會由 scheduler 存取
(uid, wid, username, printer, pages, status, created_at)
Windows Server
目前應該會開兩個 instance ,一個處理發送 print request ,另一個處理 query 們(因為 query 很快)
從 gRPC 接收檔案跟 request 並發到 printer
流程:gRPC -> windows printerUtils -> sumatrapdf.exe 送出列印 request -> 取得 jobID -> return