1

Kademliaライブラリを使用して P2P ネットワークを作成します。ノードがネットワークに参加したら、ユーザーがコマンドラインでキーを取得したり、ネットワークにタプルを配置したりできるようにしたいと考えています。

私の問題は、I/O が接続をブロックしていることです。これは、ユーザーが入力している間にノードがネットワークから切断されることを意味します。

私のコードは次のとおりです。

from kademlia.network import Server
from twisted.internet import reactor, stdio
from twisted.python import log
from twisted.internet.task import LoopingCall
import sys

log.startLogging(sys.stdout)

def usi(server):
    key = str(raw_input())
    value = str(raw_input())
    print("Putting data: (" + key + ";" + value + ")")
    server.set(key, value).addCallback(done)

def done(res):
    print "Key put:"
    print res

def boostrapDone(found, server, key):
    if len(found) == 0:
        print 'could not bootstrap'
        reactor.stop()
    server.set(key, 'value').addCallback(done)

srv = Server()
srv.saveStateRegularly('out.pik')
srv.listen(8887)
srv.bootstrap([('127.0.0.1', 8888)]).addCallback(boostrapDone, srv, 'test')
loop = LoopingCall(usi, srv)
loop.start(2)
reactor.run()

この問題に関するいくつかの SO の質問を読みました。ツイストされた例から stdin.py と stdio.py の例を読みましたが、ツイストされたプロトコルで StandardIO を使用する必要があるようです。しかし、Kademlia はプロトコルの使用を簡素化するために高レベルのクラス (サーバー) を使用しており、ライブラリを変更せずにノンブロッキング I/O を取得できるかどうかはわかりません。

編集:私はreactor.callInThreadそのように使用しようとしました:

def usi(server):
    while True:
        key = str(raw_input())
        value = str(raw_input())
        print("Putting data: (" + key + ";" + value + ")")
        server.set(key, value).addCallback(done)

def done(res):
    print "Key put:"
    print res

def boostrapDone(found, server, key):
    if len(found) == 0:
        print 'could not bootstrap'
        reactor.stop()
    server.set(key, 'value').addCallback(done)

srv = Server()
srv.saveStateRegularly('out.pik')
srv.listen(8887)
srv.bootstrap([('127.0.0.1', 8888)]).addCallback(boostrapDone, srv, 'test')
reactor.callInThread(usi, srv)
reactor.run()

動作しているように見えますが、ノードが他のノードからの応答を取得できず、それらをバケットから削除してネットワークにタプルを配置できなくなることがあるので、まだ何か間違っていると思います。(私はなんとかバグを再現しました。ユーザー入力に5秒以上かかると発生するようです。kademliaは他のノードからの応答を受信できず、タイムアウトします)

4

0 に答える 0