摘要:要完成這些,實現必須支持中繼,雖然它應該是可選的,并且能夠被終端用戶關閉連接中繼應該作為傳輸來實現,以便對上層透明中繼的實現,可參考啟用多種網絡拓撲不同的系統有不同的需求,進而導致不同的拓撲結構。
目前進度為80%, 持續更新...
1 介紹在開發IPFS(星際文件系統)的過程中,我們遇到了很多在異構設備之上運行分布式文件系統所帶來的若干挑戰,這些設備具有不同的網絡設置和能力。在這個過程中,我們必須重新審視整個網絡堆棧和詳細的解決方案,以克服由多個網絡層級和多種協議設計所施加的障礙,而不打破兼容性或再造技術。
為了構建這個庫,我們專注于獨立解決問題,創建具有復雜抽象的復雜的解決方案,當把關注點進行組合時,可以為P2P對等應用程序提供一個可靠的工作環境。
1.1 動機
libp2p 是我們建立分布式系統的集體經驗的結果,因為它對開發者負責,決定他們希望應用程序如何與網絡中的其他人進行交互,并支持配置和可擴展性,而不是對網絡SETU做出假設。P.
本質上,使用LIPP2P的對等體應該能夠使用各種不同的傳輸來與另一個對等體通信,包括連接中繼,以及在不同的協議上進行協商,按需協商。
1.2 目標libp2p 規范及其實現的目標是:
允許使用各種:
傳輸協議: TCP、UDP、SCTP、UDT、UTP、QIC、SSH等
認證傳輸協議:TLS,DTLS,CurveCP,SSH等
高效使用套接字(連接重用)
使對等體之間的通信在一個套接字上復用(避免握手開銷)
使用協商過程使多種協議和不同協議版本在對等體之間使用
向后兼容
能在現有系統中工作
利用當前網絡技術的全部能力
有 NAT 穿透功能
允許中繼連接
啟用加密通道
有效利用底層傳輸(例如本地流復用、本地AUTH等)。
?本節向讀者介紹了網絡棧的可用協議和體系結構。我們的目標是提供推斷結論的基礎,并理解為什么 libp2p 提出了這些需求和體系結構.
2.1 客戶端-服務器模型客戶端-服務器模型表明信道兩端的雙方具有不同的角色,它們支持不同的服務和/或具有不同的能力,或者換句話說,他們講不同的協議。
構建客戶機-服務器應用程序成為主流趨勢有以下幾個原因:
數據中心內部的帶寬遠遠高于客戶端可以互相連接的帶寬。
數據中心資源相當便宜,由于有效的使用和散裝備貨。
開發人員和系統管理員更容易對應用程序進行細粒度的控制。
減少了要處理的異構系統的數量(雖然這個數字仍然相當可觀)。
像NAT這樣的系統使得客戶機很難彼此查找并進行通信,迫使開發者執行非常聰明的hack來穿透這些障礙
Protocols started to be designed with the assumption that a developer will create a client-server application from the start.
我們甚至學會了如何使用Internet上的網關隱藏分布式系統的所有復雜性,使用協議來執行點對點操作(如HTTP),使得應用程序不透明地查看和理解每一次調用的服務調用級聯.
libP2P提供了一種從客戶端-服務器偵聽器向撥號器偵聽器交互的方法,其中不隱含哪些實體、撥號器或偵聽器具有哪些能力或能夠執行哪些操作。現在在兩個應用程序之間建立連接是一個需要解決的多層問題,并且這些連接不應該有目的偏向,而應該支持多個其他協議來工作在已建立的連接之上。在客戶機-服務器模型中,發送來自客戶端的先前請求的服務器被稱為推送模型,它通常會增加更多的復雜性;相比之下,在撥號偵聽器模型中,兩個實體可以獨立地執行請求。
2.2 通過解決方案對網絡棧協議進行分類在深入到LIPP2P協議之前,重要的是了解已經廣泛使用和部署的協議的多樣性,這有助于維護今天的簡單抽象。例如,當我們考慮HTTP連接時,人們可能天真地認為HTTP/TCP/IP是涉及的主要協議,但實際上更多的協議參與進來,這取決于使用情況、涉及的網絡等。諸如DNS、DHCP、ARP、OSPF、以太網、802.11(Wi-Fi)等許多協議都涉及進來。看看ISPs內部網絡,會發現更多的信息.
此外,值得注意的是,傳統的7層OSI模型表征不適合于 libp2p. 作為替代的是,我們基于它們的角色來分類協議,即它們解決的問題。OSI模型的上層面向應用之間的點對點鏈路,而 libp2p 協議在各種不同的安全模型下更傾向于具有不同功能,不同大小的網絡。不同的 libp2p 協議可以具有相同的角色(在OSI模型中,這將是“地址相同的層”),這意味著多個協議可以同時運行,所有處理一個角色(而不是傳統的OSI堆疊中的每層協議)。例如,Bootstrap列表、mDNS、DHT發現 和 PEX 都是“對等發現”的形式,它們可以共存甚至協同。
2.2.1 構建物理鏈接
Ethernet
Wi-Fi
Bluetooth
USB
2.2.2 尋址機器或進程
IPv4
IPv6
Hidden addressing, like SDP
2.2.3 發現對等節點或服務?ARP
DHCP
DNS
Onion
2.2.4 通過網絡路由消息
RIP(1, 2)
OSPF
BZGP
PPP
Tor
I2P
cjdns??2.2.5 傳輸?TCP?UDP
UDT
QUIC
WebRTC data channel
2.2.6 應用程序之間協商一致的通信語義
RMI
Remoting
RPC
HTTP
?雖然我們目前有一系列的協議可供我們的服務進行通信,但解決方案的豐富性和多樣性也產生了自身的問題。目前,應用程序難以通過多種傳輸機制(例如,在瀏覽器應用程序中缺少TCP/UDP棧)來支持和使用。
也沒有“存在性鏈接”,這意味著沒有一個對等體在多個傳輸中聲明自己的概念,因此其他對等體可以保證它總是相同的對等體。
?
3 需求和注意事項 3.1 Transport agnostic(不確定的傳輸機制)?libp2p 是不依賴具體傳輸機制的,所以它可以運行在任何傳輸協議上。它甚至不依賴于IP,它可以運行在NDN、XI和其他新的互聯網體系結構之上.
為了支持不同類型的傳輸機制,libp2p 使用 multiaddr,一種自描述尋址格式。這使得 libp2p 能夠在系統中任意地處理地址,并且支持網絡層中的各種傳輸協議。libp2p 中地址的實際格式是
ipfs-addr,以IPFS節點ID結束的 multi-addr。例如,這些都是有效的 ipfs-addrs:
# IPFS over TCP over IPv6 (typical TCP) /ip6/fe80::8823:6dff:fee7:f172/tcp/4001/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu # IPFS over uTP over UDP over IPv4 (UDP-shimmed transport) /ip4/162.246.145.218/udp/4001/utp/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu # IPFS over IPv6 (unreliable) /ip6/fe80::8823:6dff:fee7:f172/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu # IPFS over TCP over IPv4 over TCP over IPv4 (proxy) /ip4/162.246.145.218/tcp/7650/ip4/192.168.0.1/tcp/4001/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu # IPFS over Ethernet (no IP) /ether/ac:fd:ec:0b:7c:fe/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu
注意:當前,尚不存在不可靠的實現。定義和使用不可靠傳輸的協議接口尚未定義。有關不可靠VS可靠傳輸的更多信息,請參見此處。在WebRTC的上下文中,在 這里 輸入 CTRL+F搜索“可靠”。
3.2 多重多路復用(Multi-multiplexing)libp2p 協議是多個協議的集合。為了節省資源,并使連接更容易,libp2p 可以通過一個端口,如TCP或UDP端口,根據所使用的傳輸來執行其所有操作。libp2p 可以通過點到點連接來復用它的許多協議。這種復用是用于可靠的流和不可靠的數據報。
libp2p 比較務實。它試圖在盡可能多的配置中使用,以模塊化和靈活的方式來適應各種用例,并盡可能少地選擇。因此,libp2p 網絡層提供了我們松散地稱之為“多重多路復用”的內容:
多個網絡接口的多路復用
多個傳輸協議的多路復用
多個對等連接的多路復用
可以復用多個客戶端協議
每個協議/連接可以多路復用多個流(SPDY、HTTP2、QIC、SSH)
流量控制(背壓,公平性)
用不同的臨時密鑰加密每個連接
舉個例子,假設一個IPFS節點:
偵聽特定的TCP/IP地址
偵聽不同的TCP/IP地址
偵聽特定的SCTP/UDP/IP地址
偵聽特定的UDT/UDP/IP地址
具有與另一個節點X的多個連接
具有與另一個節點Y的多個連接
每個連接都有多個流打開
和 X 節點之間通過HTTP2協議復用流
和 Y 節點之間通過SSH復用流
掛載在 libp2p 頂部的協議為 每個對等節點使用一個流
掛載在 libp2p 頂部的協議為 每個對等節點使用多個流
如果不提供這種級別的靈活性將不可能在各種平臺、場景或網絡配置中使用 libp2p。
所有實現都支持所有的選擇并不重要;關鍵的是,規范足夠靈活,允許實現精確地使用他們所需要的。這確保了復雜的用戶或應用程序約束不排除 libp2p 作為選項。
在 libp2p 之上的通信可能是:?
加密的
簽名的(沒有加密, 防篡改)
clear(沒有加密,也沒有簽名)
我們同時作了安全和性能考慮. 加密通信在數據中心內部高性能通信場景下不是很必要.
我們推薦:
默認加密所有的通信
實現需要被審計
除非絕對必要,用戶通常只需要加密通信
Libp2p 采用類似TLS的加密套件.
Note: 我們不直接使用 TLS, 因為我們不需要 CA 系統包. 大多數 TLS 實現都非常龐大. Since libp2p model begins with keys, libp2p only needs to apply ciphers. 這只是整個 TLS 標準中很小的一部分.
3.4 NAT穿透網絡地址轉換在英特網上無處不在. Not only are most consumer devices behind many layers of NAT,?but most data center nodes are often behind NAT for security or virtualization reasons.
As we move into containerized deployments, this is getting worse. IPFS的實現 需要 提供一個方法來穿透 NAT, 否則操作可能會受到影響. 即使要用真實IP地址運行的節點也必須實現NAT穿越技術,因為它們可能需要建立與NAT后面的對等體的連接.
Libp2p 采用了類 ICE 的協議完成了完整的 NAT 穿透. 他并不完全是 ICE, 因為 IPFS 網絡提供了通過IPFS協議中繼通信的可能性, 用于協調穿孔甚至中繼通信.
建議在實現中使用諸多可用的NAT穿透庫之一,例如 libnice、libwebrtc 或 natty. 總而言之,NAT穿透必須是可互操作的.
3.5 中繼(Relay)然而,對于對稱的NATS,容器和VM NAT,以及其他不可能繞過的NATS,libp2p 必須回退到中繼通信,以建立一個完整的連通圖。要完成這些,實現必須支持中繼,雖然它應該是可選的,并且能夠被終端用戶關閉.
連接中繼應該作為傳輸來實現,以便對上層透明.
中繼的實現,可參考 p2p-circuit transport.
不同的系統有不同的需求,進而導致不同的拓撲結構。在P2P文獻中,我們可以發現這些拓撲被列舉為:非結構化的、結構化的、混合的和集中式的.
集中式拓撲是在Web應用基礎設施中最常見的拓撲結構,它要求給定的服務或服務群存在于已知的靜態地址,以便其他服務能夠訪問它們。非結構化網絡代表了一種P2P網絡類型,其中網絡拓撲結構是完全隨機的,或者至少是非確定性的,而結構化網絡具有隱組織的方式。混合網絡是前兩者的混合體.
考慮到這一點,libp2p 必須準備好執行不同的路由機制和對等點發現,以便構建將使服務能夠傳播消息或找到彼此的路由表.
libp2p 還通過記錄解決了網絡內部資源的可發現性問題。記錄是一個數據單元,可以被數字簽名、時間戳和/或與其他方法一起使用,以使其具有短暫的有效性。這些記錄保存諸如網絡中存在的資源的位置或可用性等信息。這些資源可以是數據、存儲、CPU周期和其他類型的服務。
libp2p 不應該限制資源的位置,而應該提供在網絡中或旁路通道去方便查找資源的方式.
3.8 消息傳輸(Messaging)高效的消息傳遞協議提供以最小等待時間傳遞內容的方法和/或支持用于分發的大型和復雜拓撲。LIPP2P試圖結合多播和PUBSUB的發展來滿足這些需求.
3.9 命名(Naming)網絡的變化和應用應該讓使用者不感知具體的網絡拓撲結構,命名便解決了這個問題.
4 架構Libp2p 是遵循UNIX理念設計的, 它由很多易于創建和測試的小組件組成. 這些組件應該便于替換,以適應不同的技術或場景,并使其能夠隨著時間的推移而升級.
雖然不同的對等體可以根據它們的能力來支持不同的協議,但是任何對等體都可以充當撥號器和/或監聽器,用于連接其他節點,一旦建立起的連接可以從兩端重新使用,從而消除客戶端和服務器之間的區別.
libp2p 接口在多個子系統上充當薄的粘合劑,以便對等體能夠通信。只要它們尊重標準化的接口,這些子系統就可以建立在其他子系統的頂部。這些子系統適合的主要領域是:
點對點路由 - 機制來決定哪些節點用于路由特定消息。這種路由可以遞歸地、迭代地或甚至在廣播/組播模式下完成.
Swarm - 處理所有從LBP2P中打開“流”部分的內容,從協議復用、流復用、NAT穿越和連接中繼,同時支持多路傳輸.
存儲和分發記錄的系統。記錄是其他系統用于信令、建立鏈接、宣布對等或內容等的小條目。它們在更廣泛的互聯網上與DNS有相似的作用.
發現-發現或識別網絡中的其他對等體.
這些子系統中的每一個都公開了一個眾所周知的接口(見第6章),并且可以相互使用以實現其目標。系統的全局概覽:
libp2p
Peer Routing
Swarm
Distributed Record Store
Discovery
4.1 Peer Routing
對等路由子系統公開一個接口,以標識消息在DHT中應該路由到哪些對等點。它接收一個密鑰并且必須返回一個或多個 PeerInfo 對象.
我們提出了兩個可能的對等路由子系統的例子,第一個基于 Kademlia DHT,第二個基于 mDNS. 然而,只要實現相同的期望和接口,就可以實現更多的對等路由機制.
kad-routing
mDNS-routing
Other-routing-mechanisms
Peer Routing
4.1.1 kad-routing
kad-routing 路由實現了 Kademlia 路由表,其中每個節點持有一組k桶,每個桶包含來自網絡中其他對等點的多個 PeerInfo 對象.
4.1.2 mDNS-routing
mDNS路由 使用 mDNS 探針來識別局域網節點是否具有給定的密鑰,或者它們只是簡單地存在.
4.2.1 Stream Muxer
流復用器必須實現接口流復用器提供的接口.
4.2.2 Protocol Muxer
協議復用是在應用層級別處理的,而不是在端口級別(不同的服務/協議在不同端口監聽)的常規方式. 這使得我們能夠過支持多個協議在同一個套接字中進行加密,從而節省了為多個端口進行NAT穿透的成本.
協議復用是通過多流協議來完成的, 該協議使用 multicodec 來協商不同類型的流(協議).
4.2.3 Transport?
4.2.4 Crypto
4.2.5 Identify
Identify is one of the protocols mounted on top of Swarm, our Connection handler. However, it follows and respects the same pattern as any other protocol when it comes to mounting it on top of Swarm. Identify enables us to trade listenAddrs and observedAddrs between peers, which is crucial for the working of IPFS. Since every socket open implements REUSEPORT, an observedAddr by another peer can enable a third peer to connect to us, since the port will be already open and redirect to us on a NAT.
4.2.6 回放(Replay)
See Circuit Relay.
4.3.1 Record
Follows IPRS spec.
4.3.2 abstract-record-store??4.3.3 kad-record-store
4.3.4 mDNS-record-store
4.3.5 s3-record-store
4.4 Discovery4.4.1 mDNS-discovery
mDNS-發現 是一種在局域網上使用 mDNS 的發現協議。它發射了mDNS信標來查找是否有更多的對等體可用。局域網節點對于對等協議是非常有用的,因為它們的低延遲鏈路.
mDNS-發現是一種獨立的協議,不依賴于任何其他的 libp2p 協議。在不依賴其他基礎設施的情況下,mDNS-發現 可以產生局域網中可用的對等點. 這在內聯網、與互聯網主干斷開的網絡以及暫時失去鏈路的網絡中尤其有用.
mDNS-discovery 可以針對每個服務進行配置(i.e. 即僅發現參與特定協議的對等體,如IPFS), 還有私有網絡(發現屬于專用網絡的對等體).
我們正在探索加密 mDNS-discovery beacons 的方式 (使得本地網絡中的其他節點無法識別正在使用的服務), though the nature of mDNS will always reveal local IP addresses.
隱私注意:mDNS 在局域網中進行廣告,在同一本地網絡中向聽眾顯示IP地址。不推薦使用隱私敏感的應用程序或太公開的路由協議.
4.4.2 random-walk
隨機游走是DHTS(具有路由表的其他協議)的發現協議。它進行隨機DHT查詢,以便快速了解大量的對等體。這導致DHT(或其他協議)收斂得更快,而在初始階段需要承擔一定負載開銷.
4.4.3 bootstrap-list
Bootstrap列表是一種發現協議,它使用本地存儲來緩存網絡中可用的高度穩定的(和一些可信的)對等點的地址。這允許協議“找到網絡的其余部分”。這基本上與DNS自舉的方式相同(盡管注意到,通過設計改變DNS引導列表——“點域”地址——不容易做到).
該列表應該存儲在長期本地存儲中,無論這意味著本地節點(例如磁盤)。
協議可以將默認列表硬編碼或采用標準代碼分發機制(如DNS)進行傳送。
在大多數情況下(當然在IPFS的情況下),引導列表應該是用戶可配置的,因為用戶可能希望建立多帶帶的網絡,(or place their reliance and trust in specific nodes)或者將它們的信任和信任放在特定的節點中.
4.5.1 PubSub
參考 https://github.com/libp2p/spe...
4.5.1.1 實現
PubSub 開發正在進行中, 用 floodsub 作為初始協議, 隨后是 gossipsub, 這是2018年5月發布的alpha版本.
Floodsub 的實現包括:
go-libp2p-floodsub: 參考 此篇 作為上下文. 還有 這篇 關于 gossipsub;
rust-libp2p-floodsub: @jamesray1 正基于 gossipsub 之上研究和開發. Js-libp2p-floodsub.
4.5.2 IPNS
5 Data structures網絡協議主要處理以下數據結構:
PrivateKey: 節點的私鑰
PublicKey: 節點的公鑰
PeerId: 節點公鑰的hash
PeerInfo: 包含節點的 PeerId, 及其已知的 multiaddr 對象.
Transport: 用于建立與其他對等體的連接. 參考?https://github.com/libp2p/int...
Connection: 節點之間的點對點連接. 必須實現?https://github.com/libp2p/int...
Muxed-Stream: 雙工通信信道.
Stream-Muxer: 流復用器. 必須實現?https://github.com/libp2p/int...
Record: IPLD(IPFS鏈接數據) 描述了實現 IPRS 的對象.
multiaddr: 自描述的網絡地址. 參考 https://github.com/multiforma...
multicodec: 自描述的編碼類型. 參考 https://github.com/multiforma...
multihash: 自描述的hash. 參考?https://github.com/multiforma...
接口
=====
libp2p 是多個協議的集合,它們一起工作,提供一個可以與任何其他網絡可尋址進程對話的公共實體接口。這是通過將現有的協議和實現擺在一組顯式接口中來實現的:對等路由、發現、Stream Muxing、傳輸、連接等。
6.1 libp2plibp2p, 作為頂級模塊,為其它接口提供 libp2p 實例, must offer an interface for dialing to a peer and plugging in all of the modules (e.g. which transports) we want to support. We present the libp2p interface and UX in section 6.6, after presenting every other module interface.
6.2 Peer RoutingA Peer Routing 模塊為 libp2p 提供節點查找其它節點 PeerInfo 信息的方式, 以便連接節點. 最簡單的形式, Peer Routing 模塊需要一個接口,其接收一個 "key", 并返回一個 PeerInfo 的集合. 關于接口和測試可參考 https://github.com/libp2p/int...
6.3 SwarmCurrent interface available and updated at:
https://github.com/libp2p/js-...
?6.3.1 Transport
https://github.com/libp2p/int...
6.3.2 Connection
https://github.com/libp2p/int...
6.3.3 Stream Muxing
https://github.com/libp2p/int...
https://github.com/libp2p/int...
6.5 Peer DiscoveryA Peer Discovery module interface should return PeerInfo objects, as it finds new peers to be considered by our Peer Routing modules.
6.6 libp2p interface and UXlibp2p 實現應該使它能夠以編程方式實例化,或者使用以前編譯過的庫,并且已經進行了一些協議決策,以便用戶可以重用或擴展.
程序化構建一個LIPP2P實例?
用JavaScript實現的例子, 可以被映射到其他語言:
var Libp2p = require(‘libp2p’) var node = new Libp2p() // add swarm instance node.addSwarm(swarmInstance) // add one or more Peer Routing mechanisms node.addPeerRouting(peerRoutingInstance) // add a Distributed Record Store node.addDistributedRecordStore(distriburedRecordStoreInstance)
配置 libp2p 非常簡單,因為大多數配置來自于實例化多個模塊,一個接一個.
撥號和偵聽與對等體的連接
理想情況下,libp2p 使用自己的機制(Peer Routing and Record Store)找到撥號給給定對等點的方法.
node.dial(PeerInfo)
若要接收傳入連接,請指定要處理的一個或多個協議:
node.handleProtocol("", function (duplexStream) { })
查找對等節點
找到對等點是通過對等路由,所以接口是相同的.
存儲和檢索記錄
像查找對等體一樣,通過記錄存儲來完成記錄的存儲和檢索,所以接口是相同的。
Efforts like NDN and XIA are new architectures for the internet, which are closer to the model IPFS uses than what IP provides today. IPFS will be able to operate on top of these architectures trivially, as these are no assumptions made about the network stack in the protocol. Implementations will likely need to change, but changing implementations is vastly easier than changing protocols.
8 實現在實現不同的模塊和功能時,libp2p2 的實現應該(推薦)遵循一定級別的粒度,以便公共接口易于暴露、測試和檢查與其他實現的互操作性.
這是當前 libp2p 存在的模塊列表:
libp2p(entry point)
Swarm
libp2p-swarm
libp2p-identify
libp2p-ping
Transports
Interface-transport
Interface-connection
libp2p-tcp
libp2p-udp
libp2p-udt
libp2p-utp
libp2p-webrtc
libp2p-cjdns
Stream Muxing
Interface-stream-muxer
libp2p-spdy
libp2p-multiplex
Crypto Channel
libp2p-tls
libp2p-secio
Peer Routing
libp2p-kad-routing
libp2p-mDNS-routing
Discovery
libp2p-mdns-discovery
libp2p-random-walk
libp2p-railing
Distributed Record Store
libp2p-record
interface-record-store
libp2p-distributed-record-store
libp2p-kad-record-store
Generic
PeerInfo
PeerId
multihash
multiaddr
multistream
multicodec
ipld
repo
當前已知實現(WIP):
JavaScript - https://github.com/libp2p/js-...
Go - https://github.com/ipfs/go-li...
Python - https://github.com/candeira/p...
Rust - https://github.com/libp2p/rus...
8.1 集群(Swarm)8.1.1 Swarm Dialer
集群撥號器管理到目標對等體的成功連接,給定一個地址流作為輸入,并且確保遵守速率限制等約定.
為此,我們設計了以下的撥號邏輯:
DialPeer(peerID) { if PeerIsBeingDialed(peerID) { waitForDialToComplete(peerID) return BestConnToPeer(peerID) } StartDial(peerID) waitForDialToComplete(peerID) return BestConnToPeer(peerID) } StartDial(peerID) { addrs = getAddressStream(peerID) addrs.onNewAddr(function(addr) { if rateLimitCanDial(peerID, addr) { doDialAsync(peerID, addr) } else { rateLimitScheduleDial(peerID, addr) } }) } // doDialAsync starts dialing to a specific address without blocking. // when the dial returns, it releases rate limit tokens, and if it // succeeded, will finalize the dial process. doDialAsync(peerID, addr) { go transportDial(addr, function(conn, err) { rateLimitReleaseTokens(peerID, addr) if err != null { // handle error } dialSuccess(conn) }) } // rateLimitReleaseTokens checks for any tokens the given dial // took, and then for each of them, checks if any other dial is waiting // for any of those tokens. If waiting dials are found, those dials are started // immediately. Otherwise, the tokens are released to their pools. rateLimitReleaseTokens(peerID, addr) { tokens = tokensForDial(peerID, addr) for token in tokens { dial = dialWaitingForToken(token) if dial != null { doDialAsync(dial.peer, dial.addr) } else { token.release() } } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/24146.html
摘要:我們將在這一章源碼倉庫全解析第五章檢索服務礦工的配置操作中介紹與存儲市場并駕齊驅而又息息相關的檢索市場,以及體系中另一重要角色檢索服務礦工的基本配置操作。 對不起,你們可能關注了一個愛拖更的公眾號... 不過不拖更,可能這篇也不會有這么多 猛料... 歡迎大家來到第五章,經過前章 《【Filecoin源碼倉庫全解析】第四章:存儲需求方(用戶)的配置操作》的內容閱讀后,我們應該對存儲需求...
摘要:基于版本基于版本。由于中英行文差異,完全的逐字逐句翻譯會很冗余啰嗦。譯者在翻譯中同時參考了谷歌百度有道翻譯的譯文以及編程思想第四版中文版的部分內容對其翻譯死板,生造名詞,語言精煉度差問題進行規避和改正。 來源:LingCoder/OnJava8 主譯: LingCoder 參譯: LortSir 校對:nickChenyx E-mail: 本書原作者為 [美] Bru...
摘要:概述經過半年的搗鼓,終于將協議全篇翻譯完成。現在將所有章節全部整理到一篇文章中,方便大家閱讀。如果大家想看具體的翻譯文檔,可以去我的中查看。大家有相關類型的需要,建議大家可以嘗試下。 概述 經過半年的搗鼓,終于將 WebSocket 協議(RFC6455)全篇翻譯完成。現在將所有章節全部整理到一篇文章中,方便大家閱讀。如果大家想看具體的翻譯文檔,可以去我的GitHub中查看。 具體章節...
摘要:全稱,中文名星際文件系統,是一個旨在創建持久且分布式存儲和共享文件的網絡傳輸協議。在網絡中的節點將構成一個分布式文件系統。使用稱為去中心化命名系統,每個文件都可以被協作命名為易讀的名字。三項目實踐利用構建一個去中心化不可篡改的分布式系統。 作者簡介:戴嘉樂( Mr.Maple ) | 前百度高級研發工程師 | IPFS應用實踐者&布道師|個人網站:https://www.daijial...
摘要:前后經過九個月,我翻譯的官方版本中文文檔可以發布第一個較為完整的版本了。這點原本是最重要的,但讓位于符合中文習慣,是因為如果譯本有機翻痕跡,給人的品質感和可信度就降低了更準確和更優雅的翻譯風格。 showImg(/img/remote/1460000006773992); 前后經過九個月,我翻譯的Spring MVC官方4.2.4版本中文文檔可以發布第一個較為完整的版本了。譯文上盡量做...
閱讀 2649·2021-11-11 16:55
閱讀 688·2021-09-04 16:40
閱讀 3086·2019-08-30 15:54
閱讀 2628·2019-08-30 15:54
閱讀 2416·2019-08-30 15:46
閱讀 411·2019-08-30 15:43
閱讀 3237·2019-08-30 11:11
閱讀 2991·2019-08-28 18:17