發表文章

目前顯示的是 6月, 2018的文章

[Twisted] Part 5: Twistier Poetry

圖片
本文由Dave的 Part 5: Twistier Poetry 翻譯而成,你可以由 Part 1 開始閱讀這個系列的文章,也可以在 這裡 找到整個系列的目錄。 Abstract Expressionism 在 Part 4 中,我們使用了Twisted建立了我們第一個詩歌用戶端,它確實能夠很好的運作,但是仍然有進步的空間。 首先,用戶端包含了一些像建立socket、從socket接收資料這種枯燥的程式碼。Twisted應該要提供實現這些事情的支援,讓我們不必每次寫新程式的時候都要去做這些事情。因為非同步I/O需要涉及一些棘手的例外處理,正如你在 用戶端程式碼 中所看到的。而且如果你希望你的程式可以跨平台執行,還有更多棘手的問題存在。如果你哪天下午有空,可以在Twisted原始碼中搜尋「WIN32」來看看這些corner cases。 目前用戶端的另外一個問題是有關錯誤處理方面。試著執行版本1的用戶端,對一個不是伺服器的埠口下載詩歌時,用戶端就會崩潰。我們可以修改這個用戶端程式,但透過今天使用的Twisted APIs來處理錯誤會更簡單。 最後,這個用戶端不能重複使用。如果另一個模組要透過我們的用戶端下載詩歌呢?如何讓其他模組知道詩歌已經下載完畢?我們無法寫一個簡單的涵式來回傳整首詩歌,這會阻塞其他模組直到整首詩歌被讀取完畢。這確實是個問題,但我們今天還沒要修正它,我們會在未來修正這個問題。 我們將會使用一些高層次的APIs和介面來解決第一、二個問題。 Twisted框架是由眾多抽象層鬆散地組合起來的,學習Twisted就是學習這些層級中有那些東西可以用,例如APIs、介面、與實現。 由於這份文章是一個介紹,所以我們不會研究每個抽象的細節,或者對Twisted的抽象進行深度的瞭解。我們只會看看最重要的部分來好好感受一下Twisted是如何組織這些抽象層,一旦你熟悉了Twisted的架構風格,你自己學習新的內容時就簡單多了。 一般來說,每個Twisted的抽象都只與一個特定的概念相關。例如,Part 4中的用戶端使用的IReadDescriptor,它就是「一個可以讀取位元組的file descriptor」的抽象。Twisted通常由定義介面來指定實現抽象的物件的行為。在學習Twisted中新的抽象時最重要的一點就是: 大多數高層級的抽象...

[Twisted] Part 4: Twisted Poetry

圖片
本文由Dave的 Part 4: Twisted Poetry 翻譯而成,你可以由 Part 1 開始閱讀這個系列的文章,也可以在 這裡 找到整個系列的目錄。 Our First Twisted Client 雖然Twisted可能較常用於撰寫伺服器,但用戶端比伺服器更簡單,我們盡量從簡單的開始。讓我們嘗試用Twisted撰寫第一個詩歌用戶端。原始碼在 twisted-client-1/get-poetry.py ,像以前一樣先啟動三個詩歌伺服器: python blocking-server/slowpoetry.py --port 10000 poetry/ecstasy.txt --num-bytes 30 python blocking-server/slowpoetry.py --port 10001 poetry/fascination.txt python blocking-server/slowpoetry.py --port 10002 poetry/science.txt 然後像這樣執行用戶端: python twisted-client-1/get-poetry.py 10000 10001 10002 然後你會看到一些像這樣的輸出: Task 1: got 60 bytes of poetry from 127.0.0.1:10000 Task 2: got 10 bytes of poetry from 127.0.0.1:10001 Task 3: got 10 bytes of poetry from 127.0.0.1:10002 Task 1: got 30 bytes of poetry from 127.0.0.1:10000 Task 3: got 10 bytes of poetry from 127.0.0.1:10002 Task 2: got 10 bytes of poetry from 127.0.0.1:10001 ... Task 1: 3003 bytes of poetry Task 2: 623 bytes of poetry Task 3: 653 bytes of poetry Got 3 poems in 0:00:10.134220 這些結果就像我們的非Twisted非同步用戶端一...

[Twisted] Part 3: Our Eye-beams Begin to Twist

圖片
本文由Dave的 Part 3: Our Eye-beams Begin to Twist 翻譯而成,你可以由 Part 1 開始閱讀這個系列的文章,也可以在 這裡 找到整個系列的目錄。 Doing Nothing, the Twisted Way 終於,我們將使用Twisted重新實現我們非同步詩歌用戶端。但先讓我們嘗試寫一些非常簡單的Twisted程式。正如我在Part 2中所提到,我使用Twisted 8.2.0開發這些範例,Twisted API會發生變化,但我們將使用的核心API可能改變會比較緩慢,我希望這些範例可以在許多未來的版本中使用。如果你還沒安裝Twisted,你可以在 這裡 獲得。 下面列出了絕對是最簡單的twisted程式,這個程式在twisted-intro目錄中的 basic-twisted/simple.py 中: from twisted.internet import reactor reactor.run() 你可以像這樣執行它: python basic-twisted/simple.py 正如我們在 Part 2 所見,Twisted是 reactor模式 的實現,因此它必然包含了一個代表reactor或事件迴圈的物件,而這正是所有Twisted程式的核心。我們程式的第一行引入了reactor物件,所以我們可以使用它,而第二行告訴reactor開始執行迴圈。 這個程式什麼事情也不做。你必須透過ctrl+c來終止它,否則它會永遠運行下去。通常對於我們想監視的I/O,我們會給迴圈一個或多個file descriptors (例如連接到詩歌伺服器)。後面我們會看到如何做到這件事,但是現在我們的reactor卡住了。注意這並不是一個不斷循環的 忙碌迴圈(busy loop) ,如果你的螢幕上有個CPU監視器,你不會發現任何由無限迴圈引起的CPU使用率尖峰。事實上,我們的程式沒有使用任何的CPU,這個reactor被卡在 圖5 的迴圈頂端,等待著一個永遠不會發生的事件(具體來說,是等待一個沒有file descriptors的select呼叫)。 我們即將讓這個程式變得更有趣,但我們已經可以得出幾個結論: Twisted的reactor迴圈只有通過呼叫reactor.run()來啟動。 reactor迴圈是在...

[Twisted] Part 2: Slow Poetry and the Apocalypse

圖片
本文由Dave的 Part 2: Slow Poetry and the Apocalypse 翻譯而成,你可以由 Part 1 開始閱讀這個系列的文章,也可以在 這裡 找到整個系列的目錄。 My Assumptions About You 在展開討論前,我假設你已經有過用Python寫同步程式的經歷,並且至少知道一點有關Python的Socket程式設計的經驗。如果你從沒有寫過Socket程式,或許你可以去看看 Socket模組的文件 ,尤其是後面的範例程式。如果你沒有用過Python的話,那這份介紹往後的部分可能相當難以理解。 My Assumptions About Your Computer 我一般是在Linux上使用Twisted,這個系列的範例也是在Linux完成的。首先聲明的是我並沒有故意讓程式碼依賴於Linux,但我所講述的一些內容可能僅適應於Linux和其它的類Unix系統(比如MAC OSX或FreeBSD)。WIndows是個奇怪詭異的地方,如果你想嘗試在它上面學習這個系列,除了衷心的同情外,我無法為你提供更多的訊息。 我將假設你已經安裝了近期版本的 Python 和 Twisted 。我所提供的範例程式是基於Python2.5和Twisted8.2.0(譯註:我已將程式碼改為Python 3.6與Twisted 17.9.0可用的範例,可於我的 GitHub 下載)。 你可以在單機上運行所有的範例程式,也可以在網路系統上運行它們。但是為了學習非同步程式設計的基礎機制,單機上學習是比較理想的。 Getting the example code 範例可用由我的 公開git儲存庫 來 clone 或下載 zip 或 tar 檔案。如果可以使用 git 或其他可以讀取git儲存庫的版本控制系統,那麼建議使用這個方法,因為我會隨著時間不斷更新範例,你會比較容易保持範例是最新的。下面是clone儲存庫的git command: git clone git://github.com/jdavisp3/twisted-intro.git 本教程的其餘部分將假定你擁有範例程式的最新副本,並且在其最上層目錄(具有README文件的目錄)中開啟了多個shell。 Slow Poetry 雖然CPU的處理速度遠遠快於網路,但網路的處理速度...

[Twisted] Part 1: In Which We Begin at the Beginning

圖片
Preface 最近有人在 Twisted mailing list 中 提出 像「為任務緊急的人提供一份Twisted介紹」的這種需求。坦白說,這裡的文章並沒有辦法快速的介紹,尤其對於Twisted框架和基於Python 的非同步程式設計而言,可能短時間無法講清楚。因此,如果你時間緊急,這裡恐怕不是你想找的資料。 我相信如果對非同步程式設計模型一無所知,快速的介紹同樣無法讓你對其有所理解,至少你得稍微懂點基礎知識吧。 我已經用Twisted框架幾年了,因此思考過我當初是怎麼學習它(學得很慢)並發現學習它的最大難度並不在Twisted本身,而在於對其模型的理解,只有理解了這個模型,你才能更好去撰寫和理解非同步程式的程式。 以多數免費軟體的標準來看,大部分Twisted的代碼寫得很清晰,其線上文件也非常好。但是沒有建立良好的心智模型,不管是讀Twisted codebase、用Twisted寫程式、或者閱讀大部分的文件,你都會感到非常的傷腦筋。 所以這份介紹的第一部分是來幫助你建立心智模型,之後我們才會介紹Twisted的功能。實際上,一開始,我們並不會使用Twisted,相反,會使用簡單的Python來說明一個非同步模型是如何工作的。我們在初次學習Twisted的時,會從你平常都不會直接使用的底層的方面講起。Twisted是一個高度抽象的系統,因此在使用它時,你會體會到其巨大的影響力。但當你開始學習Twisted,尤其在嘗試著理解它是如何工作時,許多抽象的層次可能會造成麻煩。所以,我們準備來個從內到外,從底層開始學習它。 一旦你有了基礎知識,我相信你會發現閱讀 Twisted文件 或 瀏覽原始碼 會變得更簡單,讓我們開始吧! The Models 為了與非同步程式設計模型對比,我們來回顧一下兩個大家都熟悉的模型。在闡述過程中,我們假設一個程式,它由三個概念上不同的任務(taks)所組成,這些任務必須都完成後程式才算完成。在此,除了規定這些任務都要完成自己工作外,我們先不作具體的解釋,後面我們會慢慢具體瞭解它們。請注意:在此我用「任務」這個詞,這意味著它需要完成一些事情。 第一個模型是單執行緒的同步模型,如圖1所示: 圖1.同步模型 這是最簡單的程式設計方式。在一個時間點內,只能有一個任務在執行,並且前一個任務結束後另一個任務才能開始。如果任...