jspurefix 5.10.4 → 5.10.6
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.
- package/ATDL_PLAN.md +82 -14
- package/README.md +24 -0
- package/dist/buffer/elastic-buffer.js +3 -3
- package/dist/buffer/elastic-buffer.js.map +1 -1
- package/dist/transport/ascii/ascii-session-msg-factory.d.ts +1 -1
- package/dist/transport/ascii/ascii-session-msg-factory.js +2 -2
- package/dist/transport/ascii/ascii-session-msg-factory.js.map +1 -1
- package/dist/transport/ascii/ascii-session.d.ts +6 -0
- package/dist/transport/ascii/ascii-session.js +72 -8
- package/dist/transport/ascii/ascii-session.js.map +1 -1
- package/dist/transport/session/fix-session.d.ts +1 -1
- package/dist/transport/session/fix-session.js.map +1 -1
- package/jsfix.test_client.txt +62 -62
- package/jsfix.test_server.txt +72 -72
- package/package.json +1 -1
- package/src/buffer/elastic-buffer.ts +13 -3
- package/src/transport/ascii/ascii-session-msg-factory.ts +8 -2
- package/src/transport/ascii/ascii-session.ts +115 -7
- package/src/transport/session/fix-session.ts +12 -2
package/ATDL_PLAN.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# FIXatdl renderer and end-to-end test harness
|
|
2
2
|
|
|
3
|
-
Design notes from 2026-08-08. Nothing is built yet. This
|
|
4
|
-
can start from the thinking rather than redo it.
|
|
3
|
+
Design notes from 2026-08-08, fixtures added 2026-08-09. Nothing is built yet. This
|
|
4
|
+
exists so the next session can start from the thinking rather than redo it.
|
|
5
5
|
|
|
6
|
-
**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
**Where this lives:** staying in jspurefix for now (decided 2026-08-09). It is not
|
|
7
|
+
engine work and will want its own repository once there is code, but the back-end half
|
|
8
|
+
is a jspurefix acceptor and there is no benefit to a second repository holding only a
|
|
9
|
+
markdown file.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ engine. Move it when the code starts.
|
|
|
15
15
|
A broker publishes a FIXatdl document per algorithm: an XML definition of its
|
|
16
16
|
parameters and the order ticket used to fill them in. An EMS — Bloomberg EMSX,
|
|
17
17
|
Flextrade, Portware, Fidessa, ITG Triton — renders the ticket from that document, and
|
|
18
|
-
the values map onto FIX tags
|
|
18
|
+
the values map onto FIX tags.
|
|
19
19
|
|
|
20
20
|
The observed pain, in more than one shop: getting a definition rendered is cobbled
|
|
21
21
|
together, and **you cannot tell whether a definition is sound until a vendor renders
|
|
@@ -98,12 +98,80 @@ is FIXML-shaped and is not a good fit for this.
|
|
|
98
98
|
|
|
99
99
|
~1,500 lines of interpreter, zero runtime dependencies.
|
|
100
100
|
|
|
101
|
+
## Fixtures
|
|
102
|
+
|
|
103
|
+
The expression engine is only as good as what it is tested against, and this is the
|
|
104
|
+
part most likely to be underestimated. Real broker documents vary enormously and most
|
|
105
|
+
are proprietary — the user has worked at a bank where every algo was defined in ATDL,
|
|
106
|
+
none of it publishable.
|
|
107
|
+
|
|
108
|
+
### routefire/rf-fix-atdl
|
|
109
|
+
|
|
110
|
+
`rf_strategies-v1.1.xml` — the first public fixture, 184 lines, 7 strategies (TWAP,
|
|
111
|
+
VWAP, PVOL, ISO, FAST, ULMT, RLMT).
|
|
112
|
+
|
|
113
|
+
What it settles:
|
|
114
|
+
|
|
115
|
+
- **Version is 1.1.** Namespaces are `.../FIXatdl-1-1/Core`, `/Validation`, `/Layout`,
|
|
116
|
+
`/Flow`, `/Timezones`. Target 1.1 and stop worrying about it.
|
|
117
|
+
- **Strategy identification is an attribute of `<Strategies>`:**
|
|
118
|
+
`strategyIdentifierTag="847"` and `versionIdentifierTag="7621"`, with each
|
|
119
|
+
`<Strategy>` carrying `wireValue`. So the algorithm is named on the wire in tag 847
|
|
120
|
+
and the parameters go elsewhere.
|
|
121
|
+
- **Parameters carry their own `fixTag`** — `126`, `168`, and customs `8001`–`8004`
|
|
122
|
+
here. This resolves the earlier open question about `NoStrategyParameters`: the
|
|
123
|
+
mapping is *data driven per parameter*, not a per-broker configuration switch. Build
|
|
124
|
+
it from the `fixTag` attribute; treat the strategy-parameters group as a second
|
|
125
|
+
mode for documents that omit `fixTag`, not as the default.
|
|
126
|
+
- Useful attributes in the wild: `use="required|optional"`, `minValue`/`maxValue`,
|
|
127
|
+
`localMktTz`, `initValue`, `initValueMode`, `increment`.
|
|
128
|
+
|
|
129
|
+
**What it does not exercise, which matters more.** This file is a skeleton — good for
|
|
130
|
+
proving the parser, nearly useless for proving the interpreter:
|
|
131
|
+
|
|
132
|
+
| | |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `StateRule` | **none at all** — zero occurrences |
|
|
135
|
+
| Control types | only `Clock_t`, `SingleSpinner_t`, `TextField_t` |
|
|
136
|
+
| Parameter types | only `Float_t`, `Int_t`, `UTCTimestamp_t` |
|
|
137
|
+
| `EnumPair` | none — so no dropdowns, no radio groups, no checkboxes |
|
|
138
|
+
| Validation | two `val:StrategyEdit`, each a single `val:Edit`, operator `GT` only |
|
|
139
|
+
| `logicOperator` / `editRef` | none — no AND/OR, no reusable named edits |
|
|
140
|
+
| `flow:` | namespace declared, never used |
|
|
141
|
+
|
|
142
|
+
So it will not tell us whether the hard half is right. Enable/disable/visibility logic
|
|
143
|
+
is entirely absent, and validation never gets beyond one field-to-field comparison.
|
|
144
|
+
|
|
145
|
+
### What a representative fixture needs
|
|
146
|
+
|
|
147
|
+
Worth building by hand from experience rather than waiting to find one. Aim to cover:
|
|
148
|
+
|
|
149
|
+
- `StateRule` driving `enabled`, `visible` and value assignment, keyed off another
|
|
150
|
+
control's value
|
|
151
|
+
- a `StateRule` chain — B depends on A, C depends on B — to prove evaluation order and
|
|
152
|
+
catch cycles
|
|
153
|
+
- `DropDownList_t` and `RadioButtonList_t` with `EnumPair` (`wireValue` distinct from
|
|
154
|
+
`uiRep`, which is where renderers commonly go wrong)
|
|
155
|
+
- `CheckBox_t` and its `checkedEnumRef` / `uncheckedEnumRef`
|
|
156
|
+
- `val:Edit` with `logicOperator="AND"` / `"OR"` and nested edits
|
|
157
|
+
- `val:Edit` comparing against a literal `value=` as well as `field2=`
|
|
158
|
+
- a named `<val:Edit id="...">` referenced by `editRef`, since reuse is where scoping
|
|
159
|
+
bugs live
|
|
160
|
+
- `use="required"` interacting with a control that a `StateRule` has disabled — what
|
|
161
|
+
should validation do then? Real documents disagree, and vendors disagree with each
|
|
162
|
+
other
|
|
163
|
+
- a deliberately broken document, so the tool's error reporting is exercised too
|
|
164
|
+
|
|
101
165
|
## Open questions for next session
|
|
102
166
|
|
|
103
|
-
1. Own repository or a folder here
|
|
104
|
-
2. Which
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
167
|
+
1. ~~Own repository or a folder here?~~ Settled: stays here for now.
|
|
168
|
+
2. ~~Which FIXatdl version?~~ Settled: 1.1.
|
|
169
|
+
3. ~~How do parameters map onto the order?~~ Settled: per-parameter `fixTag`, with the
|
|
170
|
+
strategy-parameters group as a fallback mode.
|
|
171
|
+
4. Can any further public documents be found, or is the hand-built fixture above the
|
|
172
|
+
realistic path? The user has significant algo trading experience and can produce
|
|
173
|
+
something representative — that is likely to be worth more than another public file
|
|
174
|
+
of the routefire kind.
|
|
175
|
+
5. What does the harness do when a `StateRule` disables a `required` parameter? Decide
|
|
176
|
+
deliberately and document it, because it is the sort of thing that differs between
|
|
177
|
+
EMSs and is exactly what the tool exists to surface.
|
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ A fast, fully native TypeScript [FIX protocol](https://www.fixtrading.org/) engi
|
|
|
13
13
|
- [Quickstart](#quickstart)
|
|
14
14
|
- [Session Configuration](#session-configuration)
|
|
15
15
|
- [Customising the Logon](#customising-the-logon)
|
|
16
|
+
- [Accepting or refusing a logon](#accepting-or-refusing-a-logon)
|
|
16
17
|
- [TLS](#tls)
|
|
17
18
|
- [Body length padding](#body-length-padding)
|
|
18
19
|
- [Persistence & Recovery](#persistence--recovery)
|
|
@@ -168,6 +169,29 @@ Most counterparties want a tag on the Logon the standard message does not carry.
|
|
|
168
169
|
|
|
169
170
|
A field named here must also be declared on `Logon` in the dictionary the session loads, or the encoder has no tag to write it to and will say so in the log. For values computed at run time, or for a header a counterparty stamps differently, supply your own session message factory. See [docs/custom-logon.md](docs/custom-logon.md) for the whole picture.
|
|
170
171
|
|
|
172
|
+
### Accepting or refusing a logon
|
|
173
|
+
|
|
174
|
+
`onLogon` is where an acceptor decides who gets a session. Return `true` to let the handshake finish; return `false` and the peer is sent a `Logout` explaining why and then disconnected — `onReady` is never reached and no heartbeat starts. The application learns the outcome through `onStopped(error)`.
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
protected onLogon (view: MsgView, user: string, password: string): boolean {
|
|
178
|
+
return user === 'js-client' && password === this.expectedPassword
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Credentials usually have to be checked against something the engine cannot wait on synchronously — an http api, a database, a secrets store. Return a promise and the session waits for it:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
protected async onLogon (view: MsgView, user: string, password: string): Promise<boolean> {
|
|
186
|
+
const account = await this.directory.lookup(user)
|
|
187
|
+
return account?.enabled === true && await account.verify(password)
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
While that promise is pending the transport is paused and anything the peer sends is queued, then replayed in order once the verdict arrives — a counterparty that pipelines messages behind its Logon will not have them dropped or reordered. If the promise rejects, the logon is refused rather than allowed through, and the rejection message is carried to the peer.
|
|
192
|
+
|
|
193
|
+
An initiator can use the same hook: there `onLogon` fires on the acceptor's logon response, so returning `false` refuses the counterparty that answered.
|
|
194
|
+
|
|
171
195
|
### TLS
|
|
172
196
|
|
|
173
197
|
Add a `tls` block under `application.tcp`. The `ca` field is only needed for self-signed certificates; commercial vendors will supply this for you. `script/getKey.ps1` will generate a self-signed CA + client/server pair (requires `openssl` on the path).
|
|
@@ -19,7 +19,7 @@ const mathjs_1 = require("mathjs");
|
|
|
19
19
|
const tsyringe_1 = require("tsyringe");
|
|
20
20
|
const di_tokens_1 = require("../runtime/di-tokens");
|
|
21
21
|
let ElasticBuffer = ElasticBuffer_1 = class ElasticBuffer {
|
|
22
|
-
constructor(size = 6 * 1024, returnTo =
|
|
22
|
+
constructor(size = 6 * 1024, returnTo = 64 * 1024) {
|
|
23
23
|
this.size = size;
|
|
24
24
|
this.returnTo = returnTo;
|
|
25
25
|
this.ptr = 0;
|
|
@@ -50,7 +50,7 @@ let ElasticBuffer = ElasticBuffer_1 = class ElasticBuffer {
|
|
|
50
50
|
}
|
|
51
51
|
setPos(ptr) {
|
|
52
52
|
const r = this.ptr;
|
|
53
|
-
if (ptr >= 0 && ptr <= this.
|
|
53
|
+
if (ptr >= 0 && ptr <= this.buffer.length) {
|
|
54
54
|
this.ptr = ptr;
|
|
55
55
|
}
|
|
56
56
|
return r;
|
|
@@ -130,7 +130,7 @@ let ElasticBuffer = ElasticBuffer_1 = class ElasticBuffer {
|
|
|
130
130
|
const shrink = this.stretched > this.returnTo;
|
|
131
131
|
if (shrink) {
|
|
132
132
|
this.buffer = Buffer.allocUnsafe(this.returnTo);
|
|
133
|
-
this.stretched = this.
|
|
133
|
+
this.stretched = this.returnTo;
|
|
134
134
|
}
|
|
135
135
|
return shrink;
|
|
136
136
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elastic-buffer.js","sourceRoot":"","sources":["../../src/buffer/elastic-buffer.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsciiChars } from './ascii/ascii-chars'\nimport { format } from 'mathjs'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../runtime/di-tokens'\n\n@injectable()\nexport class ElasticBuffer {\n private buffer: Buffer\n private ptr: number = 0\n private stretched: number\n\n constructor (@inject(DITokens.elasticBufferSize) public readonly size: number = 6 * 1024,\n @inject(DITokens.elasticBufferReturnSize) public readonly returnTo: number = 6 * 1024) {\n this.size = Math.max(1, this.size)\n this.buffer = Buffer.allocUnsafe(this.size)\n this.returnTo = Math.max(this.size, this.returnTo)\n this.stretched = this.size\n }\n\n private static precisionRound (n: number, precision: number): number {\n const factor: number = Math.pow(10, precision)\n return Math.round(n * factor) / factor\n }\n\n private static HowManyDigits (v: number): number {\n v = Math.abs(v)\n let digits: number = 0\n let w: number = v\n while (w > 0) {\n ++digits\n w = Math.floor(w / 10)\n }\n return Math.max(digits, 1)\n }\n\n public currentSize (): number {\n return this.stretched\n }\n\n public getPos (): number {\n return this.ptr\n }\n\n public setPos (ptr: number): number {\n const r = this.ptr\n if (ptr >= 0 && ptr <= this.size) {\n this.ptr = ptr\n }\n return r\n }\n\n public get (pos: number): number {\n return this.buffer[pos]\n }\n\n public writeBoolean (v: boolean): number {\n this.writeChar(v ? AsciiChars.Y : AsciiChars.N)\n return this.ptr\n }\n\n public switchChar (c: number): number {\n this.buffer[this.ptr - 1] = c\n return this.ptr\n }\n\n public saveChar (c: number): number {\n this.buffer[this.ptr++] = c\n return this.ptr\n }\n\n public writeChar (c: number): number {\n if (c > 255) throw new Error(`can't write ${c} to a byte`)\n this.checkGrowBuffer(1)\n this.buffer[this.ptr++] = c\n return this.ptr\n }\n\n public writeString (s: string): number {\n const begin = this.ptr\n this.checkGrowBuffer(s.length)\n const buffer = this.buffer\n this.ptr += buffer.write(s, begin, s.length, 'ascii')\n return this.ptr\n }\n\n public writeBuffer (v: Buffer): number {\n const begin = this.ptr\n this.checkGrowBuffer(v.length)\n const buffer = this.buffer\n const srcLen: number = v.length\n this.ptr += v.copy(buffer, begin, 0, srcLen)\n return this.ptr\n }\n\n public writeWholeNumber (n: number): number {\n const digits: number = ElasticBuffer.HowManyDigits(n)\n let reserve = digits\n const sign: number = Math.sign(n)\n let p: number = Math.pow(10, digits - 1)\n let v: number = Math.abs(n)\n if (sign < 0) {\n reserve++\n }\n this.checkGrowBuffer(reserve)\n const buffer = this.buffer\n if (sign < 0) {\n buffer[this.ptr++] = AsciiChars.Minus\n }\n while (p >= 1) {\n const d: number = Math.floor(v / p)\n v -= d * p\n p /= 10\n buffer[this.ptr++] = AsciiChars.Zero + d\n }\n\n return this.ptr\n }\n\n public writeNumber (v: number, places: number = 13): number {\n const rounded: number = Math.floor(v)\n const fraction: number = ElasticBuffer.precisionRound(v - rounded, places)\n if (fraction === 0) {\n // integer\n return this.writeWholeNumber(v)\n } else {\n // decimal with fraction turn to string\n const s: string = format(v, { notation: 'fixed' })\n return this.writeString(s)\n }\n }\n\n public reset (): boolean {\n this.ptr = 0\n const shrink = this.stretched > this.returnTo\n if (shrink) {\n this.buffer = Buffer.allocUnsafe(this.returnTo)\n this.stretched = this.size\n }\n return shrink\n }\n\n public slice (): Buffer {\n return this.buffer.subarray(0, this.ptr)\n }\n\n public copy (): Buffer {\n const m = Buffer.alloc(this.ptr)\n this.buffer.copy(m, 0, 0, this.ptr)\n return m\n }\n\n public clone (): ElasticBuffer {\n const cloned = new ElasticBuffer(this.ptr)\n this.buffer.copy(cloned.buffer, 0, 0, this.ptr)\n cloned.setPos(this.ptr)\n return cloned\n }\n\n public writePaddedHundreds (v: number): number {\n if (v > 999) throw new Error(`can't write ${v} as hundreds padding`)\n this.checkGrowBuffer(3)\n const buffer = this.buffer\n const zero: number = AsciiChars.Zero\n const units: number = v % 10 + zero\n v = v / 10\n const tens: number = v % 10 + zero\n v = v / 10\n buffer[this.ptr++] = v % 10 + zero\n buffer[this.ptr++] = tens\n buffer[this.ptr++] = units\n return this.ptr\n }\n\n public writePaddedTensUnits (v: number): number {\n if (v > 99) throw new Error(`can't write ${v} as hundreds padding`)\n this.checkGrowBuffer(2)\n const buffer = this.buffer\n const zero: number = AsciiChars.Zero\n const units: number = v % 10 + zero\n v = v / 10\n buffer[this.ptr++] = v % 10 + zero\n buffer[this.ptr++] = units\n return this.ptr\n }\n\n public patchPaddedNumberAtPos (ptr: number, numToWrite: number, padding: number): void {\n let digits: number = ElasticBuffer.HowManyDigits(numToWrite)\n const saved: number = this.ptr\n this.ptr = ptr\n const buffer = this.buffer\n while (digits++ < padding) {\n buffer[this.ptr++] = AsciiChars.Zero\n }\n this.writeWholeNumber(numToWrite)\n this.ptr = saved\n }\n\n public toString (ptr: number = this.ptr): string {\n return this.buffer.toString('ascii', 0, ptr)\n }\n\n public checksum (ptr: number = this.ptr): number {\n const cks: number = this.sum(ptr)\n return cks % 256\n }\n\n public sum (ptr: number = this.ptr): number {\n let total: number = 0\n ptr = Math.min(ptr, this.ptr)\n const buffer = this.buffer\n for (let idx: number = 0; idx < ptr; idx++) {\n total += buffer[idx]\n }\n return total\n }\n\n public getWholeNumber (start: number, vend: number): number {\n const buffer = this.buffer\n let sign = 1\n let raised = vend - start\n switch (buffer[start]) {\n case AsciiChars.Minus: {\n --raised\n sign = -1\n ++start\n break\n }\n case AsciiChars.Plus: {\n --raised\n ++start\n break\n }\n }\n let i: number = Math.pow(10, raised)\n let num: number = 0\n let scan: number = start\n\n while (scan <= vend) {\n const p: number = buffer[scan++]\n const d: number = p - AsciiChars.Zero\n num += d * i\n i /= 10\n }\n\n return num * sign\n }\n\n public getString (start: number, end: number): string {\n return this.buffer.toString('ascii', start, end)\n }\n\n public getBuffer (start: number, end: number): Buffer {\n return this.buffer.subarray(start, end)\n }\n\n public getBoolean (start: number): boolean {\n const b: number = this.buffer[start]\n return b === AsciiChars.Y\n }\n\n public getFloat (start: number, vend: number): number | null {\n let n: number = 0\n let digits: number = 0\n let dotPosition: number = 0\n const buffer = this.buffer\n let sign = 1\n switch (buffer[start]) {\n case AsciiChars.Minus: {\n sign = -1\n start++\n break\n }\n case AsciiChars.Plus: {\n start++\n break\n }\n }\n const len = vend - start\n let i: number = Math.pow(10, len - 1)\n for (let j: number = start; j <= vend; ++j) {\n const p: number = buffer[j]\n if (p >= AsciiChars.Zero && p <= AsciiChars.Nine) {\n const d: number = p - AsciiChars.Zero\n ++digits\n n += d * i\n i /= 10\n } else if (p === AsciiChars.Dot) {\n if (dotPosition > 0) {\n return null\n }\n dotPosition = j - start\n } else if (digits > 0) {\n return null\n }\n }\n const power: number = dotPosition === 0 ? 0 : len - dotPosition\n const raised = dotPosition === 0 ? 10 : Math.pow(10, -1 * power)\n const round = dotPosition === 0 ? 1 : Math.pow(10, power)\n const val = n * raised * sign\n return Math.round(val * round) / round\n }\n\n public checkGrowBuffer (required: number): void {\n let buffer = this.buffer\n let size = buffer.length\n const ptr = this.ptr\n if (size - ptr >= required) {\n return\n }\n while (size - ptr < required) {\n size *= 2\n }\n const old = buffer\n buffer = Buffer.allocUnsafe(size)\n old.copy(buffer, 0, 0, this.ptr)\n this.buffer = buffer\n this.stretched = size\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"elastic-buffer.js","sourceRoot":"","sources":["../../src/buffer/elastic-buffer.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsciiChars } from './ascii/ascii-chars'\nimport { format } from 'mathjs'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../runtime/di-tokens'\n\n@injectable()\nexport class ElasticBuffer {\n private buffer: Buffer\n private ptr: number = 0\n private stretched: number\n\n /**\n * A buffer grown to serve a large message keeps that capacity across reset, so a\n * steady stream of similarly sized messages does not re-grow (and re-allocate) on\n * every single message. Only a buffer that has ballooned past returnTo is handed\n * back, so one pathological message cannot pin a large allocation for the life of\n * the session. Unlike cspurefix - where the discarded array goes to a shared\n * ArrayPool - the retained bytes are held by this instance, so an acceptor with\n * many connections holds up to this much per connection. Tune with\n * DITokens.elasticBufferReturnSize.\n */\n constructor (@inject(DITokens.elasticBufferSize) public readonly size: number = 6 * 1024,\n @inject(DITokens.elasticBufferReturnSize) public readonly returnTo: number = 64 * 1024) {\n this.size = Math.max(1, this.size)\n this.buffer = Buffer.allocUnsafe(this.size)\n this.returnTo = Math.max(this.size, this.returnTo)\n this.stretched = this.size\n }\n\n private static precisionRound (n: number, precision: number): number {\n const factor: number = Math.pow(10, precision)\n return Math.round(n * factor) / factor\n }\n\n private static HowManyDigits (v: number): number {\n v = Math.abs(v)\n let digits: number = 0\n let w: number = v\n while (w > 0) {\n ++digits\n w = Math.floor(w / 10)\n }\n return Math.max(digits, 1)\n }\n\n public currentSize (): number {\n return this.stretched\n }\n\n public getPos (): number {\n return this.ptr\n }\n\n public setPos (ptr: number): number {\n const r = this.ptr\n if (ptr >= 0 && ptr <= this.buffer.length) {\n this.ptr = ptr\n }\n return r\n }\n\n public get (pos: number): number {\n return this.buffer[pos]\n }\n\n public writeBoolean (v: boolean): number {\n this.writeChar(v ? AsciiChars.Y : AsciiChars.N)\n return this.ptr\n }\n\n public switchChar (c: number): number {\n this.buffer[this.ptr - 1] = c\n return this.ptr\n }\n\n public saveChar (c: number): number {\n this.buffer[this.ptr++] = c\n return this.ptr\n }\n\n public writeChar (c: number): number {\n if (c > 255) throw new Error(`can't write ${c} to a byte`)\n this.checkGrowBuffer(1)\n this.buffer[this.ptr++] = c\n return this.ptr\n }\n\n public writeString (s: string): number {\n const begin = this.ptr\n this.checkGrowBuffer(s.length)\n const buffer = this.buffer\n this.ptr += buffer.write(s, begin, s.length, 'ascii')\n return this.ptr\n }\n\n public writeBuffer (v: Buffer): number {\n const begin = this.ptr\n this.checkGrowBuffer(v.length)\n const buffer = this.buffer\n const srcLen: number = v.length\n this.ptr += v.copy(buffer, begin, 0, srcLen)\n return this.ptr\n }\n\n public writeWholeNumber (n: number): number {\n const digits: number = ElasticBuffer.HowManyDigits(n)\n let reserve = digits\n const sign: number = Math.sign(n)\n let p: number = Math.pow(10, digits - 1)\n let v: number = Math.abs(n)\n if (sign < 0) {\n reserve++\n }\n this.checkGrowBuffer(reserve)\n const buffer = this.buffer\n if (sign < 0) {\n buffer[this.ptr++] = AsciiChars.Minus\n }\n while (p >= 1) {\n const d: number = Math.floor(v / p)\n v -= d * p\n p /= 10\n buffer[this.ptr++] = AsciiChars.Zero + d\n }\n\n return this.ptr\n }\n\n public writeNumber (v: number, places: number = 13): number {\n const rounded: number = Math.floor(v)\n const fraction: number = ElasticBuffer.precisionRound(v - rounded, places)\n if (fraction === 0) {\n // integer\n return this.writeWholeNumber(v)\n } else {\n // decimal with fraction turn to string\n const s: string = format(v, { notation: 'fixed' })\n return this.writeString(s)\n }\n }\n\n public reset (): boolean {\n this.ptr = 0\n const shrink = this.stretched > this.returnTo\n if (shrink) {\n this.buffer = Buffer.allocUnsafe(this.returnTo)\n this.stretched = this.returnTo\n }\n return shrink\n }\n\n public slice (): Buffer {\n return this.buffer.subarray(0, this.ptr)\n }\n\n public copy (): Buffer {\n const m = Buffer.alloc(this.ptr)\n this.buffer.copy(m, 0, 0, this.ptr)\n return m\n }\n\n public clone (): ElasticBuffer {\n const cloned = new ElasticBuffer(this.ptr)\n this.buffer.copy(cloned.buffer, 0, 0, this.ptr)\n cloned.setPos(this.ptr)\n return cloned\n }\n\n public writePaddedHundreds (v: number): number {\n if (v > 999) throw new Error(`can't write ${v} as hundreds padding`)\n this.checkGrowBuffer(3)\n const buffer = this.buffer\n const zero: number = AsciiChars.Zero\n const units: number = v % 10 + zero\n v = v / 10\n const tens: number = v % 10 + zero\n v = v / 10\n buffer[this.ptr++] = v % 10 + zero\n buffer[this.ptr++] = tens\n buffer[this.ptr++] = units\n return this.ptr\n }\n\n public writePaddedTensUnits (v: number): number {\n if (v > 99) throw new Error(`can't write ${v} as hundreds padding`)\n this.checkGrowBuffer(2)\n const buffer = this.buffer\n const zero: number = AsciiChars.Zero\n const units: number = v % 10 + zero\n v = v / 10\n buffer[this.ptr++] = v % 10 + zero\n buffer[this.ptr++] = units\n return this.ptr\n }\n\n public patchPaddedNumberAtPos (ptr: number, numToWrite: number, padding: number): void {\n let digits: number = ElasticBuffer.HowManyDigits(numToWrite)\n const saved: number = this.ptr\n this.ptr = ptr\n const buffer = this.buffer\n while (digits++ < padding) {\n buffer[this.ptr++] = AsciiChars.Zero\n }\n this.writeWholeNumber(numToWrite)\n this.ptr = saved\n }\n\n public toString (ptr: number = this.ptr): string {\n return this.buffer.toString('ascii', 0, ptr)\n }\n\n public checksum (ptr: number = this.ptr): number {\n const cks: number = this.sum(ptr)\n return cks % 256\n }\n\n public sum (ptr: number = this.ptr): number {\n let total: number = 0\n ptr = Math.min(ptr, this.ptr)\n const buffer = this.buffer\n for (let idx: number = 0; idx < ptr; idx++) {\n total += buffer[idx]\n }\n return total\n }\n\n public getWholeNumber (start: number, vend: number): number {\n const buffer = this.buffer\n let sign = 1\n let raised = vend - start\n switch (buffer[start]) {\n case AsciiChars.Minus: {\n --raised\n sign = -1\n ++start\n break\n }\n case AsciiChars.Plus: {\n --raised\n ++start\n break\n }\n }\n let i: number = Math.pow(10, raised)\n let num: number = 0\n let scan: number = start\n\n while (scan <= vend) {\n const p: number = buffer[scan++]\n const d: number = p - AsciiChars.Zero\n num += d * i\n i /= 10\n }\n\n return num * sign\n }\n\n public getString (start: number, end: number): string {\n return this.buffer.toString('ascii', start, end)\n }\n\n public getBuffer (start: number, end: number): Buffer {\n return this.buffer.subarray(start, end)\n }\n\n public getBoolean (start: number): boolean {\n const b: number = this.buffer[start]\n return b === AsciiChars.Y\n }\n\n public getFloat (start: number, vend: number): number | null {\n let n: number = 0\n let digits: number = 0\n let dotPosition: number = 0\n const buffer = this.buffer\n let sign = 1\n switch (buffer[start]) {\n case AsciiChars.Minus: {\n sign = -1\n start++\n break\n }\n case AsciiChars.Plus: {\n start++\n break\n }\n }\n const len = vend - start\n let i: number = Math.pow(10, len - 1)\n for (let j: number = start; j <= vend; ++j) {\n const p: number = buffer[j]\n if (p >= AsciiChars.Zero && p <= AsciiChars.Nine) {\n const d: number = p - AsciiChars.Zero\n ++digits\n n += d * i\n i /= 10\n } else if (p === AsciiChars.Dot) {\n if (dotPosition > 0) {\n return null\n }\n dotPosition = j - start\n } else if (digits > 0) {\n return null\n }\n }\n const power: number = dotPosition === 0 ? 0 : len - dotPosition\n const raised = dotPosition === 0 ? 10 : Math.pow(10, -1 * power)\n const round = dotPosition === 0 ? 1 : Math.pow(10, power)\n const val = n * raised * sign\n return Math.round(val * round) / round\n }\n\n public checkGrowBuffer (required: number): void {\n let buffer = this.buffer\n let size = buffer.length\n const ptr = this.ptr\n if (size - ptr >= required) {\n return\n }\n while (size - ptr < required) {\n size *= 2\n }\n const old = buffer\n buffer = Buffer.allocUnsafe(size)\n old.copy(buffer, 0, 0, this.ptr)\n this.buffer = buffer\n this.stretched = size\n }\n}\n"]}
|
|
@@ -6,7 +6,7 @@ export declare class AsciiSessionMsgFactory extends ASessionMsgFactory {
|
|
|
6
6
|
readonly description: ISessionDescription;
|
|
7
7
|
constructor(description: ISessionDescription, mutator?: ObjectMutator | null);
|
|
8
8
|
logon(): ILooseObject;
|
|
9
|
-
logout(text: string): ILooseObject;
|
|
9
|
+
logout(msgType: string, text: string): ILooseObject;
|
|
10
10
|
header(msgType: string, seqNum: number, time: Date, overrideData?: Partial<IStandardHeader>): ILooseObject;
|
|
11
11
|
}
|
|
12
12
|
export declare class SessionMsgFactory extends AsciiSessionMsgFactory {
|
|
@@ -16,11 +16,11 @@ class AsciiSessionMsgFactory extends a_session_msg_factory_1.ASessionMsgFactory
|
|
|
16
16
|
const o = Object.assign({ Username: description.Username, Password: description.Password, HeartBtInt: description.HeartBtInt, ResetSeqNumFlag: description.ResetSeqNumFlag, EncryptMethod: repo_1.EncryptMethod.None }, description.Logon);
|
|
17
17
|
return this.mutate(o, types_1.MsgType.Logon);
|
|
18
18
|
}
|
|
19
|
-
logout(text) {
|
|
19
|
+
logout(msgType, text) {
|
|
20
20
|
const o = {
|
|
21
21
|
Text: text
|
|
22
22
|
};
|
|
23
|
-
return this.mutate(o, types_1.MsgType.Logout);
|
|
23
|
+
return this.mutate(o, msgType !== null && msgType !== void 0 ? msgType : types_1.MsgType.Logout);
|
|
24
24
|
}
|
|
25
25
|
header(msgType, seqNum, time, overrideData) {
|
|
26
26
|
var _a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ascii-session-msg-factory.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session-msg-factory.ts"],"names":[],"mappings":";;;AAEA,uCAAqC;AACrC,4EAAoF;AAEpF,kDAKgC;AAEhC,MAAa,sBAAuB,SAAQ,0CAAkB;IAC5D,YAAsB,WAAgC,EAAE,UAAgC,IAAI;;QAC1F,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QADP,gBAAW,GAAX,WAAW,CAAqB;QAEpD,IAAI,CAAC,OAAO,GAAG,CAAA,MAAA,WAAW,CAAC,WAAW,0CAAE,QAAQ,MAAK,OAAO,CAAA;IAC9D,CAAC;IAEM,KAAK;QACV,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,MAAM,CAAC,GAAW,gBAChB,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAC9B,UAAU,EAAE,WAAW,CAAC,UAAU,EAClC,eAAe,EAAE,WAAW,CAAC,eAAe,EAC5C,aAAa,EAAE,oBAAa,CAAC,IAAI,IAK9B,WAAW,CAAC,KAAK,CACX,CAAA;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;
|
|
1
|
+
{"version":3,"file":"ascii-session-msg-factory.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session-msg-factory.ts"],"names":[],"mappings":";;;AAEA,uCAAqC;AACrC,4EAAoF;AAEpF,kDAKgC;AAEhC,MAAa,sBAAuB,SAAQ,0CAAkB;IAC5D,YAAsB,WAAgC,EAAE,UAAgC,IAAI;;QAC1F,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QADP,gBAAW,GAAX,WAAW,CAAqB;QAEpD,IAAI,CAAC,OAAO,GAAG,CAAA,MAAA,WAAW,CAAC,WAAW,0CAAE,QAAQ,MAAK,OAAO,CAAA;IAC9D,CAAC;IAEM,KAAK;QACV,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,MAAM,CAAC,GAAW,gBAChB,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAC9B,UAAU,EAAE,WAAW,CAAC,UAAU,EAClC,eAAe,EAAE,WAAW,CAAC,eAAe,EAC5C,aAAa,EAAE,oBAAa,CAAC,IAAI,IAK9B,WAAW,CAAC,KAAK,CACX,CAAA;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;IAQM,MAAM,CAAE,OAAe,EAAE,IAAY;QAC1C,MAAM,CAAC,GAAY;YACjB,IAAI,EAAE,IAAI;SACA,CAAA;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,eAAO,CAAC,MAAM,CAAC,CAAA;IAClD,CAAC;IAEM,MAAM,CAAE,OAAe,EAAE,MAAc,EAAE,IAAU,EAAE,YAAuC;;QACjG,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,MAAM,UAAU,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAA,WAAW,CAAC,eAAe,mCAAI,CAAC,CAAC,CAAA;QACxE,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QACpD,MAAM,CAAC,mBACL,WAAW,EAAE,WAAW,CAAC,WAAW,EACpC,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,WAAW,CAAC,YAAY,EACtC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,IAAI,EACjB,YAAY,EAAE,WAAW,CAAC,YAAY,EACtC,WAAW,EAAE,WAAW,CAAC,WAAW,EACpC,WAAW,EAAE,WAAW,CAAC,WAAW,IACjC,YAAY,CAChB,CAAA;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;IACzC,CAAC;CACF;AAtDD,wDAsDC;AAED,MAAa,iBAAkB,SAAQ,sBAAsB;IAC3D,YAA6B,WAAgC,EAAS,UAAgC,IAAI;QACxG,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QADA,gBAAW,GAAX,WAAW,CAAqB;QAAS,YAAO,GAAP,OAAO,CAA6B;IAE1G,CAAC;CACF;AAJD,8CAIC","sourcesContent":["import { ISessionDescription } from '../session/session-description'\nimport { ILooseObject } from '../../collections/collection'\nimport { MsgType } from '../../types'\nimport { ASessionMsgFactory, ObjectMutator } from '../session/a-session-msg-factory'\n\nimport {\n EncryptMethod,\n ILogon,\n ILogout,\n IStandardHeader\n} from '../../types/FIX4.4/repo'\n\nexport class AsciiSessionMsgFactory extends ASessionMsgFactory {\n constructor (readonly description: ISessionDescription, mutator: ObjectMutator | null = null) {\n super(description, mutator)\n this.isAscii = description.application?.protocol === 'ascii'\n }\n\n public logon (): ILooseObject {\n const description = this.description\n const o: ILogon = {\n Username: description.Username,\n Password: description.Password,\n HeartBtInt: description.HeartBtInt,\n ResetSeqNumFlag: description.ResetSeqNumFlag,\n EncryptMethod: EncryptMethod.None,\n // a counterparty demanding a tag the standard Logon does not carry needs no\n // code at all - name it under \"Logon\" in the session description. Spread last\n // so an application can also override what the engine derived, or null out a\n // field it does not want sent. See issue #93.\n ...description.Logon\n } as ILogon\n return this.mutate(o, MsgType.Logon)\n }\n\n /**\n * ISessionMsgFactory declares logout (msgType, text) and FixSession calls it that\n * way. This override used to take the text alone, so it silently bound the msg\n * type to Text and every Logout jspurefix sent carried '58=5' in place of the\n * reason - the caller's message was dropped on the floor.\n */\n public logout (msgType: string, text: string): ILooseObject {\n const o: ILogout = {\n Text: text\n } as ILogout\n return this.mutate(o, msgType ?? MsgType.Logout)\n }\n\n public header (msgType: string, seqNum: number, time: Date, overrideData?: Partial<IStandardHeader>): ILooseObject {\n const description = this.description\n const bodyLength: number = Math.max(4, description.BodyLengthChars ?? 7)\n const placeHolder = Math.pow(10, bodyLength - 1) + 1\n const o: IStandardHeader = {\n BeginString: description.BeginString,\n BodyLength: placeHolder,\n MsgType: msgType,\n SenderCompID: description.SenderCompId,\n MsgSeqNum: seqNum,\n SendingTime: time,\n TargetCompID: description.TargetCompID,\n TargetSubID: description.TargetSubID,\n SenderSubID: description.SenderSubID,\n ...overrideData\n }\n return this.mutate(o, 'StandardHeader')\n }\n}\n\nexport class SessionMsgFactory extends AsciiSessionMsgFactory {\n constructor (public readonly description: ISessionDescription, public mutator: ObjectMutator | null = null) {\n super(description, mutator)\n }\n}\n"]}
|
|
@@ -18,6 +18,7 @@ export declare abstract class AsciiSession extends FixSession {
|
|
|
18
18
|
protected readonly wildcardTarget: boolean;
|
|
19
19
|
private identityBound;
|
|
20
20
|
private bindInProgress;
|
|
21
|
+
private logonVerdictPending;
|
|
21
22
|
private readonly pendingRx;
|
|
22
23
|
private readonly clock;
|
|
23
24
|
protected constructor(config: IJsFixConfig);
|
|
@@ -42,11 +43,16 @@ export declare abstract class AsciiSession extends FixSession {
|
|
|
42
43
|
protected onSessionMsg(msgType: string, view: MsgView): void;
|
|
43
44
|
protected onMsg(msgType: string, view: MsgView): void;
|
|
44
45
|
private onMsgBeforeIdentity;
|
|
46
|
+
private rxGated;
|
|
47
|
+
private resumeRx;
|
|
45
48
|
private drainPendingRx;
|
|
46
49
|
private bindIdentity;
|
|
47
50
|
private dispatchMsg;
|
|
48
51
|
private startTimer;
|
|
49
52
|
private peerLogon;
|
|
53
|
+
private awaitLogonVerdict;
|
|
54
|
+
private completePeerLogon;
|
|
55
|
+
private rejectLogon;
|
|
50
56
|
private sendTestRequest;
|
|
51
57
|
private sendHeartbeat;
|
|
52
58
|
private tick;
|
|
@@ -29,6 +29,7 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
29
29
|
this.store = null;
|
|
30
30
|
this.registered = false;
|
|
31
31
|
this.bindInProgress = false;
|
|
32
|
+
this.logonVerdictPending = false;
|
|
32
33
|
this.pendingRx = [];
|
|
33
34
|
this.clock = new fix_clock_1.DefaultFixClock();
|
|
34
35
|
this.requestLogoutType = this.respondLogoutType = types_1.MsgType.Logout;
|
|
@@ -419,6 +420,11 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
419
420
|
this.onMsgBeforeIdentity(msgType, view);
|
|
420
421
|
return;
|
|
421
422
|
}
|
|
423
|
+
if (this.logonVerdictPending) {
|
|
424
|
+
this.sessionLogger.info(`queueing '${msgType}' received while awaiting logon verdict`);
|
|
425
|
+
this.pendingRx.push({ msgType, view: view.clone() });
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
422
428
|
this.dispatchMsg(msgType, view);
|
|
423
429
|
}
|
|
424
430
|
onMsgBeforeIdentity(msgType, view) {
|
|
@@ -441,20 +447,34 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
441
447
|
const logon = view.clone();
|
|
442
448
|
(_b = (_a = this.transport) === null || _a === void 0 ? void 0 : _a.duplex.readable) === null || _b === void 0 ? void 0 : _b.pause();
|
|
443
449
|
this.bindIdentity(peerCompId).then(() => {
|
|
444
|
-
var _a, _b;
|
|
445
450
|
this.bindInProgress = false;
|
|
446
451
|
this.identityBound = true;
|
|
447
452
|
this.dispatchMsg(types_1.MsgType.Logon, logon);
|
|
448
|
-
this.
|
|
449
|
-
(_b = (_a = this.transport) === null || _a === void 0 ? void 0 : _a.duplex.readable) === null || _b === void 0 ? void 0 : _b.resume();
|
|
453
|
+
this.resumeRx();
|
|
450
454
|
}).catch((e) => {
|
|
451
455
|
this.bindInProgress = false;
|
|
452
456
|
this.pendingRx.length = 0;
|
|
453
457
|
this.terminate(new Error(`failed to bind session identity for peer '${peerCompId}': ${e.message}`));
|
|
454
458
|
});
|
|
455
459
|
}
|
|
460
|
+
rxGated() {
|
|
461
|
+
return this.bindInProgress || this.logonVerdictPending;
|
|
462
|
+
}
|
|
463
|
+
resumeRx() {
|
|
464
|
+
var _a, _b;
|
|
465
|
+
if (this.rxGated())
|
|
466
|
+
return;
|
|
467
|
+
this.drainPendingRx();
|
|
468
|
+
if (this.rxGated())
|
|
469
|
+
return;
|
|
470
|
+
(_b = (_a = this.transport) === null || _a === void 0 ? void 0 : _a.duplex.readable) === null || _b === void 0 ? void 0 : _b.resume();
|
|
471
|
+
}
|
|
456
472
|
drainPendingRx() {
|
|
457
473
|
while (this.pendingRx.length > 0) {
|
|
474
|
+
if (this.rxGated()) {
|
|
475
|
+
this.sessionLogger.info('suspending replay - logon handshake gated again');
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
458
478
|
const queued = this.pendingRx.shift();
|
|
459
479
|
if (!queued)
|
|
460
480
|
break;
|
|
@@ -528,7 +548,7 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
528
548
|
}, interval);
|
|
529
549
|
}
|
|
530
550
|
peerLogon(view) {
|
|
531
|
-
var _a, _b
|
|
551
|
+
var _a, _b;
|
|
532
552
|
const logger = this.sessionLogger;
|
|
533
553
|
const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([types_1.MsgTag.HeartBtInt, types_1.MsgTag.SenderCompID, types_1.MsgTag.Username, types_1.MsgTag.Password]);
|
|
534
554
|
const resetSeqNumFlag = view.getTyped(types_1.MsgTag.ResetSeqNumFlag);
|
|
@@ -557,18 +577,57 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
557
577
|
const state = this.sessionState;
|
|
558
578
|
state.peerHeartBeatSecs = view.getTyped(types_1.MsgTag.HeartBtInt);
|
|
559
579
|
state.peerCompId = view.getTyped(types_1.MsgTag.SenderCompID);
|
|
560
|
-
const
|
|
561
|
-
|
|
580
|
+
const verdict = this.onLogon(view, userName, password);
|
|
581
|
+
if (typeof verdict === 'boolean') {
|
|
582
|
+
this.completePeerLogon(view, verdict, resetSeqNumFlag);
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
this.awaitLogonVerdict(view, verdict, resetSeqNumFlag);
|
|
586
|
+
}
|
|
587
|
+
awaitLogonVerdict(view, verdict, peerReset) {
|
|
588
|
+
var _a, _b;
|
|
589
|
+
const logger = this.sessionLogger;
|
|
590
|
+
logger.info('onLogon returned a promise - awaiting logon verdict');
|
|
591
|
+
this.logonVerdictPending = true;
|
|
592
|
+
const logon = view.clone();
|
|
593
|
+
(_b = (_a = this.transport) === null || _a === void 0 ? void 0 : _a.duplex.readable) === null || _b === void 0 ? void 0 : _b.pause();
|
|
594
|
+
verdict.then((accepted) => {
|
|
595
|
+
this.logonVerdictPending = false;
|
|
596
|
+
if (this.sessionState.state === tcp_1.SessionState.Stopped) {
|
|
597
|
+
logger.info('session stopped while awaiting logon verdict - discarding');
|
|
598
|
+
this.pendingRx.length = 0;
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
this.completePeerLogon(logon, accepted, peerReset);
|
|
602
|
+
if (!accepted) {
|
|
603
|
+
this.pendingRx.length = 0;
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
this.resumeRx();
|
|
607
|
+
}).catch((e) => {
|
|
608
|
+
this.logonVerdictPending = false;
|
|
609
|
+
this.pendingRx.length = 0;
|
|
610
|
+
this.rejectLogon(`onLogon failed: ${e.message}`);
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
completePeerLogon(view, accepted, peerReset) {
|
|
614
|
+
var _a;
|
|
615
|
+
const logger = this.sessionLogger;
|
|
616
|
+
logger.info(`peerLogon onLogon returns ${accepted}`);
|
|
617
|
+
if (!accepted) {
|
|
618
|
+
this.rejectLogon('logon rejected by application');
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
562
621
|
if (this.acceptor) {
|
|
563
622
|
this.setState(tcp_1.SessionState.InitiationLogonResponse);
|
|
564
623
|
logger.info('acceptor responds to logon request');
|
|
565
624
|
const weReset = this.config.description.ResetSeqNumFlag;
|
|
566
|
-
if (weReset &&
|
|
625
|
+
if (weReset && peerReset !== true) {
|
|
567
626
|
logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences');
|
|
568
627
|
this.coordinator.resetAsAcceptor().catch((e) => {
|
|
569
628
|
this.sessionLogger.warning(`coordinator.resetAsAcceptor store persist failed: ${e.message}`);
|
|
570
629
|
});
|
|
571
|
-
const transmitter = (
|
|
630
|
+
const transmitter = (_a = this.transport) === null || _a === void 0 ? void 0 : _a.transmitter;
|
|
572
631
|
if (transmitter) {
|
|
573
632
|
transmitter.msgSeqNum = 1;
|
|
574
633
|
}
|
|
@@ -593,6 +652,11 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
593
652
|
logger.info('system ready, inform app');
|
|
594
653
|
this.onReady(view);
|
|
595
654
|
}
|
|
655
|
+
rejectLogon(reason) {
|
|
656
|
+
this.sessionLogger.warning(`refusing peer logon: ${reason}`);
|
|
657
|
+
this.sendLogout(reason);
|
|
658
|
+
this.terminate(new Error(reason));
|
|
659
|
+
}
|
|
596
660
|
sendTestRequest() {
|
|
597
661
|
const factory = this.config.factory;
|
|
598
662
|
this.setState(tcp_1.SessionState.AwaitingProcessingResponseToTestRequest);
|