2015-01-15 4 views
1

나는 twisted.python.context을 사용하려고 시도하지만 처음에는 컨텍스트가 사라집니다. deferToThread.꼬인 상태에서 컨텍스트 사용

from twisted.internet import reactor, defer, threads 
from twisted.python import context 

def _print_context(msg): 
    cont = context.get('cont') 
    print "{msg}: {context}".format(msg=msg, context=cont) 

def sub_call(): 
    _print_context("In sub_call") 

@defer.inlineCallbacks 
def with_context(): 
    _print_context("before thread") 
    yield threads.deferToThread(sub_call) 
    _print_context("after thread") 
    reactor.stop() 

def test(): 
    cont = {'cont': "TestContext"} 
    context.call(cont, with_context) 
reactor.callLater(0, test) 
reactor.run() 

나는 deferToThreadsub_call에 컨텍스트가 없지만, deferToThread 이후에는 상황.

deferToThread 뒤에 컨텍스트가있는 방법이 있습니까?

답변

3

context.call은 전달 된 개체의 호출 기간에 대한 컨텍스트를 설정합니다.이 경우에는 with_context입니다.

with_context은 겹쳐진 생성기 기능입니다. 첫 번째 호출은 새 생성자를 만들고 첫 번째 yield 문까지 반복합니다. 그런 다음 실행이 일시 중지되고 호출자가 염려하는 한 호출이 반환됩니다. 이 시점에서 컨텍스트 스택이 팝되고 사용자가 제공 한 컨텍스트가 삭제됩니다.

나중에 inlineCallbacks을 구현하면 발전기가 더 반복되어 yield 문 실행 후 코드가 실행됩니다. 그러나 컨텍스트는 이미 삭제되었습니다.

쉽게 해결할 수있는 방법이 없습니다. twisted.python.context비동기 컨텍스트 관리의 문제를 해결하려고 시도하지 않습니다. 또한, twisted.python.context은 상당히 끔찍하며 프로그램을 실제로 사용하기 위해 작성해야하는 프로그램이 거의없는 경우는 거의 없습니다.

한 걸음 뒤로 물러서서 여기에서 다시 평가하는 것이 좋습니다. 클래스를 생성하고 그 인스턴스에서 인스턴스 속성을 사용하여 메소드 호출 사이에 상태를 전달하는 것이 더 나을 것입니다.

+1

고마워요. 물론 수업을 사용합니다. 이것은 단지 문제의 최소한의 예일뿐입니다. 그러나 내가 볼 수있는 유일한 해결책은 메서드 params에서 컨텍스트를 전달하는 것입니다. 나는이 해결책을 좋아하지 않지만 다른 어떤 것도 찾을 수 없다. – aborilov

+0

왜 나는 입력 값을 매개 변수로 메서드에 전달하는 솔루션을 좋아하지 않는지 궁금합니다. – Glyph

+0

@Glyph, 그것은 선택적 매개 변수이므로 각 메서드에 나타납니다.이 메서드의 대부분은이 매개 변수가 필요하지 않으며 심지어 존재하지도 않아도 다음 메서드로 전달해야합니다 . 이 매개 변수에서는 시스템에서 작업을 수행하는 사용자에 대한 정보를 전달합니다. 그리고'컨텍스트', 나는이 문제를 해결하는 최선의 해결책이라고 생각한다. – aborilov