반응형

출처
https://stackoverflow.com/questions/59371973/quickfix-python-plugin-use-case-for-testing-segmentation-fault-error

QuickFix 파이썬 플러그인 - 테스트 케이스 용도 - segmentation fault 오류

우리는 Fix 서버로부터 메세지를 주고 받기 위해 QuickFix를 사용하는 곳에서 테스트 자동화 프레임워크 (PyTest+Quickfix)를 만들었습니다. 우리가 (임의의 양으로) 많은 양의 데이터를 보낼 때 우리는 Segmentation fault 오류가 발생하였습니다. 일부의 작은 양의 테스트 케이스는 잘 작동하였습니다. QuickFix의 내부 상태가 잘못된 거라 생각합니다. (유지하는 실제 세션에 대해 알고 있음)

다음은 코드의 일부분입니다.

class MyFixApp(quickfix.Application):
    class State(Enum):
        NONE = 0
        LOGGED_IN = 1
        LOGGED_OUT = 2

    def __init__(self, config_file, timeout_seconds=1):
        super().__init__()
        self.out_messages_queue = queue.Queue()  # blocking queue of quickfix outbound messages
        self.in_messages_queue = queue.Queue()  # blocking queue of quickfix inbound messages
        self.all_messages_list = list()  # list of all quickfix messages
        self.parser = simplefix.FixParser()
        self.settings = quickfix.SessionSettings(config_file)
        self.storeFactory = quickfix.FileStoreFactory(self.settings)
        self.logFactory = quickfix.FileLogFactory(self.settings)
        self.timeout_seconds = timeout_seconds
        self.sessionID = None  # This is just a stateless collection of sender comp, target comp, etc...
        self.state = FixApp.State.NONE
        # initiate the socket last, because this may call into the
        # callbacks below and we need all the members constructed
        self.initiator = quickfix.SocketInitiator(self, self.storeFactory, self.settings, self.logFactory)

    def wait_for_next_in(self, timeout=1):
        return self.in_messages_queue.get(block=True, timeout=timeout)

    def wait_for_next_in_matching(self, subset, skipped=None, timeout=None):
        if timeout is None:
            timeout = self.timeout_seconds
        msg = self.wait_for_next_in(timeout=timeout)
        matches = FixApp.message_contains(msg, subset)
        if matches:
            return msg
        assert skipped is not None, f"expected={subset} msg={msg}"
        skipped.append(msg)
        return self.wait_for_next_in_matching(subset=subset, skipped=skipped, timeout=timeout)

    def login(self, timeout=30):
        print(f"Logging in {threading.get_ident()}")
        self.initiator.start()
        FixApp.wait_until(lambda: self.state is FixApp.State.LOGGED_IN, timeout)
        time.sleep(self.timeout_seconds)
        print(f"Logged in")

    # 30 seconds is needed for removing the session from QuickFix
    def logout(self, timeout=30):
        if not self.sessionID:
            print(f"Logging out without session")
            return
        print(f"Logging out from {self.sessionID} {threading.get_ident()}")
        self.initiator.getSession(self.sessionID).disconnect()
        FixApp.wait_until(lambda: self.state is FixApp.State.LOGGED_OUT, timeout)
        time.sleep(self.timeout_seconds)  # somehow, this needs more time. Remove this, and the following stop fails
        print(f"Logged out")
        self.initiator.stop()
        FixApp.wait_until(lambda: self.initiator.isStopped(), timeout)
        print(f"Initiator stopped")

    @staticmethod
    def wait_until(condition, timeout_sec):
        start = time.time()
        while not condition() and (time.time() - start) < timeout_sec:
            time.sleep(0.1)
        assert condition(), condition()

Stack trace:

#0  0x00007ffff7665e5b in raise () from /lib64/libpthread.so.0
#1  <signal handler called>
#2  0x00007fffee803d14 in FIX::Initiator::connect() () at C++/Initiator.cpp:139
#3  0x00007fffee7fce74 in FIX::SocketInitiator::onStart (this=0x555556a3c5d0) at C++/SocketInitiator.cpp:89
#4  0x00007fffee801cee in FIX::Initiator::startThread (p=<optimized out>) at C++/Initiator.cpp:292
#5  0x00007ffff765b594 in start_thread () from /lib64/libpthread.so.0
#6  0x00007ffff6bf400f in clone () from /lib64/libc.so.6

파이썬에서는 이 라인이 실패합니다. (줄 번호가 첨부된 코드와 일치하지 않습니다.)

Thread 0x00007ffff7fde540 (most recent call first):
  line 187 in wait_until
  line 153 in login

다음은 일치하는 라인입니다.

FixApp.wait_until(lambda: self.state is FixApp.State.LOGGED_IN, timeout)

2개의 답변 중 1개의 답변

해결 방법을 수행했습니다. 세션을 중지(stop)하는 부분을 변경했습니다. self.initiator.stop(True) + 결국 모든 세션 및 로그 파일을 제거했습니다. 이 중 하나만 하면 작동하지 않습니다.

반응형
반응형

출처 : https://stackoverflow.com/questions/33114855/reset-sequence-number-in-quickfix

quickfix에서 시퀀스 번호 리셋

나는 매주의 시작을 제외하고 로그온 시 시퀀스 번호를 리셋하지 않도록 브로커로 작업하고 있습니다. 그러나 시퀀스 번호가 이상하면 로그온 메시지의 태그 141을 사용하여 시퀀스 번호 리셋을 요청해야 합니다. 분명히 시퀀스 번호가 너무 낮아 거부된 로그온이 거부되었는지 확인하고 onlogon에 태그를 설정할 수 있습니다. 그러나 quickfix에 시퀀스 번호를 리셋해야 한다고 어떻게 알릴 수 있습니까? 이것은 시퀀스 번호에 영향을 미치는 연결 문제가 자주 발생하지 않기 때문에 테스트하기 어려운 기능입니다.

저는 quickfix의 C++ 버전을 사용합니다


1개의 답변

당신은 LOGOUT 메세지에서 적절한 메세지를 모니터해야 합니다. "msgseqnum이 너무 작다" 같은 뭔가가 발생하면, 다음 LOGON 메세지에서 리셋하도록 플래그를 설정해야 합니다. 이는 FIX::Application::fromAdmin 구현에서 합니다.

그리고 나서 당신의 FIX::Application::toAdmin 구현에서 메세지에 LOGON이 있는지 확인하고 리셋 플래그를 설정합니다. 그렇다면 당신의 세션(FIX::Session::lookupSession)을 찾아 setNextSenderMsgSeqNum(1)setNextTargetMsgSeqNum(1)를 호출합니다. 또한 당신의 플래그를 리셋합니다 :)

반응형
반응형

출처 : https://stackoverflow.com/questions/24157767/how-to-logout-fix-session

fix 세션을 로그아웃하는 방법?

저는 quickfixj를 사용하고 있습니다. 저는 "EndTrade" 같은 사용자 정의 메세지가 있고 그 메세지를 받을 때 fix session을 종료하고 싶습니다? 어떻게 할 수 있을까요? 저는 그것을 할 수 있는 방법을 찾을 수 없었습니다. new Session().logout()을 사용하는 것은 안 됩니다.


1개의 답변

제 질문의 답변을 얻었습니다. 당신은 다음 방법으로 fix session을 로그아웃 할 수 있습니다.

Session.lookupSession(sessionID).logout();
반응형
반응형

출처 : https://stackoverflow.com/questions/49774027/adding-password-to-logon-message-with-quickfix

QuickFix에서 로그온 메세지에 비밀번호 추가하기

안녕하세요. 저는 Quick Fix python에서 문제가 있습니다. 저는 거래소가 요구하는 Tag 554를 거래소로 보낼 로그온 메세지에 추가할 필요가 있지만, 어떻게 해야 할 지 잘 모르겠습니다. 내가 찾은 모든 온라인 예제는 C++ 코드이며 이를 Python으로 번역하려는 시도는 성공하지 못했습니다.

누군가가 비밀번호 태그로 로그온 메세지를 보내는 방법을 조언해 주신다면 감사하겠습니다.

 def toAdmin(self, sessionID, message):
        message.getHeader().setField(554, "password")

1개의 답변

당신의 코드는 거의 정확합니다. 당신은 실제로 당신이 그것을 실행하는 것에 대해 말하지 않았으므로 나는 당신이 그것에 대해 잘못되었다고 생각하는 것을 100% 확신할 수 없습니다.

그러나 한 가지 개선해야 할 사항이 있습니다. 로그온 메시지에만 암호를 설정하려는 것입니다.

def toAdmin(self, sessionID, message):
        if message.getHeader().getField(35) == "A":
                message.getHeader().setField(554, "password")

(Python 구문 오류를 용서하십시오. 제가 잘 아는 언어가 아닙니다.)

이것은 다른 QF 포트에서 수행하는 작업과 매우 유사합니다. 예를 들어, C# 방식에 대한 QuickFIX/n 사용자 FAQ를 참조하십시오.

반응형
반응형

출처 : https://stackoverflow.com/questions/29523954/distinguishing-between-two-quickfix-initiator-sessions

2개의 QuickFix initiator 세션을 구분하기

저는 broker로 접속하기 위한 Python binding으로 QuickFix를 사용하고 있고 config 파일에서 2 개의 initiator 세션이 있습니다. 하나는 가격을 위한 것이고 다른 것은 주문 세션을 위한 것입니다.

제 질문은 그들 중 하나만 온라인일 때 뭔가를 하고 싶습니다.

initiator = fix.SocketInitiator(application, storeFactory, settings, logFactory)
if initiator.isLoggedOn():
    function()

가격이나 주문 세션이나 로그인 된 둘 다에 관련하여 function이 호출될 것입니다. 저는 특정 initiator가 로그인되어 있을 때 알아낼 수 있을까요?


1개의 답변 중 1개의 답변

언급하신대로, 메소드 bool Initiator::isLoggedOn()는 어떤 세션이든 현재 로그인 되었는지 당신에게 알려줍니다.

특별한 세션을 확인하기 위해 bool Initiator::isConnected( const SessionID& sessionID )를 사용하세요.

SocketInitiatorInitiator로 부터 이들 둘 다를 상속합니다.

반응형

+ Recent posts