fixcore-engine 0.1.5__tar.gz → 0.1.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fixcore_engine-0.1.5/fixcore_engine.egg-info → fixcore_engine-0.1.7}/PKG-INFO +1 -1
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/session/session.py +22 -7
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7/fixcore_engine.egg-info}/PKG-INFO +1 -1
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/pyproject.toml +1 -1
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/LICENSE +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/README.md +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/__init__.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/application.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/gui.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/gui_ui/app.js +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/gui_ui/fixcore_logo.svg +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/gui_ui/index.html +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/gui_ui/style.css +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/log/__init__.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/log/base.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/log/factory.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/log/file_log.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/log/screen.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/message/__init__.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/message/cracker.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/message/data_dictionary.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/message/exceptions.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/message/field.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/message/message.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/session/__init__.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/session/session_id.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/session/session_settings.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/session/state.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/store/__init__.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/store/base.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/store/factory.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/store/file_store.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/store/memory.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/transport/__init__.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/transport/acceptor.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/transport/framer.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore/transport/initiator.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore_engine.egg-info/SOURCES.txt +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore_engine.egg-info/dependency_links.txt +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore_engine.egg-info/entry_points.txt +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore_engine.egg-info/requires.txt +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/fixcore_engine.egg-info/top_level.txt +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/setup.cfg +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_cracker.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_data_dictionary.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_file_log.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_file_store.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_framer.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_integration.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_message.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_session.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_session_id.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_store.py +0 -0
- {fixcore_engine-0.1.5 → fixcore_engine-0.1.7}/tests/test_transport.py +0 -0
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import logging
|
|
6
7
|
import time
|
|
7
8
|
from datetime import datetime, timezone
|
|
8
9
|
from typing import Awaitable, Callable
|
|
9
10
|
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
10
13
|
from fixcore.application import Application
|
|
11
14
|
from fixcore.log.base import Log
|
|
12
15
|
from fixcore.message.message import Message
|
|
@@ -111,17 +114,22 @@ class Session:
|
|
|
111
114
|
|
|
112
115
|
async def on_connect(self, send_fn: SendFn) -> None:
|
|
113
116
|
"""Called by transport when connection is established."""
|
|
117
|
+
logger.debug("[%s] on_connect: setting send_fn", self._id)
|
|
114
118
|
self._send_fn = send_fn
|
|
115
119
|
self._last_recv_time = time.monotonic()
|
|
116
120
|
|
|
117
121
|
if self._reset_on_logon:
|
|
122
|
+
logger.debug("[%s] on_connect: resetting store", self._id)
|
|
118
123
|
self._store.reset()
|
|
119
124
|
|
|
120
125
|
self._state = SessionState.LOGON_TIMEOUT
|
|
126
|
+
logger.debug("[%s] on_connect: starting timer loop", self._id)
|
|
121
127
|
self._heartbeat_task = asyncio.create_task(self._timer_loop())
|
|
122
128
|
|
|
123
129
|
if self._is_initiator:
|
|
130
|
+
logger.debug("[%s] on_connect: sending Logon", self._id)
|
|
124
131
|
await self._send_logon()
|
|
132
|
+
logger.debug("[%s] on_connect: Logon sent", self._id)
|
|
125
133
|
|
|
126
134
|
async def on_disconnect(self) -> None:
|
|
127
135
|
"""Called by transport when connection is lost."""
|
|
@@ -304,20 +312,21 @@ class Session:
|
|
|
304
312
|
# ------------------------------------------------------------------
|
|
305
313
|
|
|
306
314
|
async def _send_logon(self) -> None:
|
|
315
|
+
logger.debug("[%s] _send_logon: building Logon message", self._id)
|
|
307
316
|
msg = Message()
|
|
308
317
|
msg.header.set(TAG_MSG_TYPE, MSG_LOGON)
|
|
309
318
|
msg.set_field(TAG_ENCRYPT_METHOD, "0")
|
|
310
319
|
msg.set_field(TAG_HEART_BT_INT, str(self._heartbt_int))
|
|
311
|
-
|
|
320
|
+
logger.debug("[%s] _send_logon: calling _send_message", self._id)
|
|
312
321
|
await self._send_message(msg, is_admin=True)
|
|
313
322
|
self._logon_sent_at = time.monotonic()
|
|
323
|
+
logger.debug("[%s] _send_logon: complete", self._id)
|
|
314
324
|
|
|
315
325
|
async def _send_logout(self, text: str = "") -> None:
|
|
316
326
|
msg = Message()
|
|
317
327
|
msg.header.set(TAG_MSG_TYPE, MSG_LOGOUT)
|
|
318
328
|
if text:
|
|
319
329
|
msg.set_field(TAG_TEXT, text)
|
|
320
|
-
self._app.to_admin(msg, self._id)
|
|
321
330
|
await self._send_message(msg, is_admin=True)
|
|
322
331
|
self._state = SessionState.LOGOUT_TIMEOUT
|
|
323
332
|
|
|
@@ -326,14 +335,12 @@ class Session:
|
|
|
326
335
|
msg.header.set(TAG_MSG_TYPE, MSG_HEARTBEAT)
|
|
327
336
|
if test_req_id:
|
|
328
337
|
msg.set_field(TAG_TEST_REQ_ID, test_req_id)
|
|
329
|
-
self._app.to_admin(msg, self._id)
|
|
330
338
|
await self._send_message(msg, is_admin=True)
|
|
331
339
|
|
|
332
340
|
async def _send_test_request(self, test_req_id: str) -> None:
|
|
333
341
|
msg = Message()
|
|
334
342
|
msg.header.set(TAG_MSG_TYPE, MSG_TEST_REQUEST)
|
|
335
343
|
msg.set_field(TAG_TEST_REQ_ID, test_req_id)
|
|
336
|
-
self._app.to_admin(msg, self._id)
|
|
337
344
|
await self._send_message(msg, is_admin=True)
|
|
338
345
|
self._test_req_id = test_req_id
|
|
339
346
|
self._test_req_sent_at = time.monotonic()
|
|
@@ -343,7 +350,6 @@ class Session:
|
|
|
343
350
|
msg.header.set(TAG_MSG_TYPE, MSG_RESEND_REQUEST)
|
|
344
351
|
msg.set_field(TAG_BEGIN_SEQ_NO, str(begin_seq))
|
|
345
352
|
msg.set_field(TAG_END_SEQ_NO, str(end_seq))
|
|
346
|
-
self._app.to_admin(msg, self._id)
|
|
347
353
|
await self._send_message(msg, is_admin=True)
|
|
348
354
|
|
|
349
355
|
async def _send_sequence_reset(self, new_seq_no: int, gap_fill: bool = False) -> None:
|
|
@@ -373,7 +379,6 @@ class Session:
|
|
|
373
379
|
msg.set_field(TAG_SESSION_REJECT_REASON, str(reason))
|
|
374
380
|
if text:
|
|
375
381
|
msg.set_field(TAG_TEXT, text)
|
|
376
|
-
self._app.to_admin(msg, self._id)
|
|
377
382
|
await self._send_message(msg, is_admin=True)
|
|
378
383
|
|
|
379
384
|
# ------------------------------------------------------------------
|
|
@@ -426,7 +431,7 @@ class Session:
|
|
|
426
431
|
# ------------------------------------------------------------------
|
|
427
432
|
|
|
428
433
|
async def _send_message(self, msg: Message, *, is_admin: bool) -> None:
|
|
429
|
-
"""Stamp header, store, log, and transmit *msg*."""
|
|
434
|
+
"""Stamp header, call app callback, store, log, and transmit *msg*."""
|
|
430
435
|
seq_num = self._store.next_sender_msg_seq_num()
|
|
431
436
|
msg.header.set(TAG_BEGIN_STRING, self._id.begin_string)
|
|
432
437
|
msg.header.set(TAG_SENDER_COMP_ID, self._id.sender_comp_id)
|
|
@@ -434,7 +439,13 @@ class Session:
|
|
|
434
439
|
msg.header.set(TAG_MSG_SEQ_NUM, str(seq_num))
|
|
435
440
|
msg.header.set(TAG_SENDING_TIME, _utc_timestamp())
|
|
436
441
|
|
|
442
|
+
if is_admin:
|
|
443
|
+
self._app.to_admin(msg, self._id)
|
|
444
|
+
else:
|
|
445
|
+
self._app.to_app(msg, self._id)
|
|
446
|
+
|
|
437
447
|
raw = msg.encode()
|
|
448
|
+
logger.debug("[%s] _send_message: seq=%s len=%d", self._id, seq_num, len(raw))
|
|
438
449
|
self._store.set(seq_num, raw)
|
|
439
450
|
self._store.incr_next_sender_msg_seq_num()
|
|
440
451
|
self._last_send_time = time.monotonic()
|
|
@@ -442,7 +453,11 @@ class Session:
|
|
|
442
453
|
self._log.on_outgoing(raw.replace(b"\x01", b"|").decode("latin-1"))
|
|
443
454
|
|
|
444
455
|
if self._send_fn is not None:
|
|
456
|
+
logger.debug("[%s] _send_message: calling send_fn", self._id)
|
|
445
457
|
await self._send_fn(raw)
|
|
458
|
+
logger.debug("[%s] _send_message: send_fn returned", self._id)
|
|
459
|
+
else:
|
|
460
|
+
logger.warning("[%s] _send_message: send_fn is None — message not sent", self._id)
|
|
446
461
|
|
|
447
462
|
# ------------------------------------------------------------------
|
|
448
463
|
# Sequence number validation
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|