-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathfixsessionalgorithm.txt
153 lines (132 loc) · 4.93 KB
/
fixsessionalgorithm.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//Shahbaz Chaudhary
//shahbazc gmail com
//Persistent variables (survive session crash)
expectedInSeqNum = 1
expectedOutSeqNum = 1 (assume automatically set)
//Session level variables (do not survive session crash)
isLoggedIn = false;
isResendRequested = false;
timeOfLastIn = none
timeOfLastOut = none (assume automatically set)
sender = nothing
target = nothing
version = nothing
msg = valid message arrives
timeOfLastIn = now
//==================INCOMING=============================
//-------------FRAME DECODING & MSG VALIDATION-----------------------------
decode frame
if checksum not matches
ignore msg
warn "corrupt msg, checksum didn't match"
//-------------LOGON PROCSSING (acceptor)-----------------------------
//first message must be logon [initiator and acceptor behave differently]
if not isLoggedIn
if msg is not [logon]
ignore msg
error "first message must be [logon]"
disconnect connection
else msg is [logon]
if isAcceptor
isAuth = authenticate(msg,remoteIP) //potentially blocking
if <isAuth>
isLoggedIn = true;
initSession{
sender = msg[senderCompID]
target = msg[targetCompID]
version = msg[version]
archiveMsgs = getOldSession(version,sender,target) //potenetially blocking
expectedInSeqnum = getExectedIn(archiveMsgs)
expectedOutSeqnum = getExectedOut(archiveMsgs)
}
scheduleTimer{
every heartBeatInt seconds call
if (now - timeOfLastOut) > heartBeatInt
send [heartbeat]
if (now - timeOfLastIn) > heartBeatInt
send [test request]
if (now - timeOfLastIn) > (1.5 * heartBeantInt)
error "no heartbeats from counter party, time to die"
disconnect session
}
send [logon ack]
else <not Auth>
ignore msg
error "unknown connection"
disconnect connection
else isInitiator
isLoggedIn = true;
//initSession is done when logon msg is being sent
scheduleTimer{
every heartBeatInt seconds call
if (now - timeOfLastOut) > heartBeatInt
send [heartbeat]
if (now - timeOfLastIn) > heartBeatInt
send [test request]
if (now - timeOfLastIn) > (1.5 * heartBeantInt)
error "no heartbeats from counter party, time to die"
disconnect session
}
//-------------COMMON SESSION PROCSSING-----------------------------
//record msg (needed for resend request)
record msg
//duplicate logon (CORRECTION: check this in logon logic)
if isLoggedIn and msg is [logon]
ignore msg
error "already logged in"
send [session reject]
if msg is [sequence-reset] and gap-fill is undefined or N
if newseqnum >= expectedInSeqNum
expectedInSeqNum = newseqnum
else
ignore msg
error "can't reduce seqnums! manual intervention needed"
disconnect connection
//check seqnums
if inSeqNum = expectedInSeqNum
increment expectedInSeqNum
isResendRequested = false
else if inSeqNum < expectedInSeqNum and posdup is Y
ignore msg
else if inSeqNum < expectedInSeqNum and posdup is undefined or N
ignore msg
error "manual intervention needed!"
send [logout] with error reason
disconnect connection
else if inSeqNum > expectedInSeqNum
ignore msg
if msg is [resend-request] (CONFUSION: check this against spec)
for list of requested messages from record
if msg is [logon, logout, resendreq, heartbeat, testreq, seqreset]
send [seq-reset] with gap-fill Y
send msg with posdup = Y
if isResendRequested is false
isResendRequested = true
send [resend-request] for missing messages
if msg is [sequence-reset] and gap-fill is Y
if newseqnum >= expectedInSeqNum
expectedinSeqNum = newseqnum
else
ignore msg
error "can't reduce seqnums! manual intervention needed"
disconnect connection
//check compids and version
if sender, target or version don't match
ignore msg
error "sender, target and version must match logon"
send [session-reject]
//real session logic
//[initiator and acceptor behave differently]
if msg is [logout]
send [logout ack]
if msg is [test request]
send [heartbeat] with test request id
if msg is [resend request]
for list of requested messages from record
if msg is [logon, logout, resendreq, heartbeat, testreq, seqreset]
send [seq-reset] with gap-fill Y
send msg with posdup = Y
//==================OUTGOING=============================
fix-string = converToFIX(fix-map, version, sender, target, timestamp, seqnum)
increment outgoing seqnum
send fix-string