# 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 架構圖 ![image](https://hackmd.io/_uploads/BkoOTj_Abl.png) 從 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