Skip to content

Commit 0362bac

Browse files
authored
Merge pull request #528 from quickfixgo/fix-persist-seqnum
Resolves bug related to persisting and incrementing sequence numbers, upgrades mongodb to require replica sets, improves project docs and dev process
2 parents 3e41031 + fb2a734 commit 0362bac

File tree

16 files changed

+237
-93
lines changed

16 files changed

+237
-93
lines changed

.devcontainer/docker-compose.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,15 @@ services:
2121
# (Adding the "ports" property to this file will not forward from a Codespace.)
2222

2323
db:
24-
image: mongo:latest
24+
image: bitnami/mongodb:latest
2525
restart: unless-stopped
2626
volumes:
2727
- mongodb-data:/data/db
2828
ports:
2929
- 27017:27017
30-
# Uncomment to change startup options
31-
# environment:
32-
# MONGO_INITDB_ROOT_USERNAME: root
33-
# MONGO_INITDB_ROOT_PASSWORD: example
34-
# MONGO_INITDB_DATABASE: your-database-here
30+
environment:
31+
MONGODB_REPLICA_SET_MODE: primary
32+
ALLOW_EMPTY_PASSWORD: 'yes'
3533

3634
# Add "forwardPorts": ["27017"] to **devcontainer.json** to forward MongoDB locally.
3735
# (Adding the "ports" property to this file will not forward from a Codespace.)

.github/workflows/ci.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ jobs:
3737
env:
3838
GOLANGCI_LINT_VERSION: '1.46.2'
3939
GOLANGCI_LINT_SHA256: '242cd4f2d6ac0556e315192e8555784d13da5d1874e51304711570769c4f2b9b'
40-
- name: Test style
41-
run: make test-style
40+
- name: Run Lint
41+
run: make lint
4242

4343
build:
4444
name: build
@@ -65,6 +65,8 @@ jobs:
6565
uses: actions/checkout@v2
6666
- name: Start MongoDB
6767
uses: supercharge/[email protected]
68+
with:
69+
mongodb-replica-set: replicaset
6870
- name: Install ruby
6971
uses: ruby/setup-ruby@v1
7072
with:

.golangci.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ run:
77
linters:
88
disable-all: true
99
enable:
10-
- deadcode
1110
- dupl
1211
- gofmt
1312
- goimports
@@ -17,7 +16,6 @@ linters:
1716
- misspell
1817
- revive
1918
- unused
20-
- varcheck
2119
- staticcheck
2220

2321
linters-settings:

Makefile

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,3 @@
1-
GOBIN = $(shell go env GOBIN)
2-
ifeq ($(GOBIN),)
3-
GOBIN = $(shell go env GOPATH)/bin
4-
endif
5-
GOX = $(GOBIN)/gox
6-
GOIMPORTS = $(GOBIN)/goimports
7-
ARCH = $(shell uname -p)
8-
9-
# ------------------------------------------------------------------------------
10-
# dependencies
11-
12-
# If go install is run from inside the project directory it will add the
13-
# dependencies to the go.mod file. To avoid that we change to a directory
14-
# without a go.mod file when downloading the following dependencies
15-
16-
$(GOX):
17-
(cd /; GO111MODULE=on go install github.com/mitchellh/gox@latest)
18-
19-
$(GOIMPORTS):
20-
(cd /; GO111MODULE=on go install golang.org/x/tools/cmd/goimports@latest)
21-
22-
# ------------------------------------------------------------------------------
231

242
all: vet test
253

@@ -29,39 +7,29 @@ clean:
297
generate: clean
308
mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -pkg-root=github.com/quickfixgo/quickfix/gen ../spec/*.xml
319

32-
generate-dist:
33-
cd ..; go run quickfix/cmd/generate-fix/generate-fix.go quickfix/spec/*.xml
34-
35-
test-style:
36-
GO111MODULE=on golangci-lint run
37-
38-
.PHONY: format
39-
format: $(GOIMPORTS)
40-
GO111MODULE=on go list -f '{{.Dir}}' ./... | xargs $(GOIMPORTS) -w -local github.com/quickfixgo/quickfix
41-
4210
fmt:
43-
go fmt `go list ./... | grep -v quickfix/gen`
11+
gofmt -l -w -s $(shell find . -type f -name '*.go')
4412

4513
vet:
4614
go vet `go list ./... | grep -v quickfix/gen`
4715

4816
test:
4917
MONGODB_TEST_CXN=mongodb://db:27017 go test -v -cover . ./datadictionary ./internal
5018

51-
build-src:
52-
go build -v `go list ./...`
53-
54-
build-test-srv:
55-
cd _test; go build -o echo_server ./test-server/
19+
linters-install:
20+
@golangci-lint --version >/dev/null 2>&1 || { \
21+
echo "installing linting tools..."; \
22+
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.46.2; \
23+
}
5624

57-
build: build-src build-test-srv
58-
59-
test-ci:
60-
go test -v -cover . ./datadictionary ./internal
25+
lint: linters-install
26+
golangci-lint run
6127

62-
generate-ci: clean
63-
mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -pkg-root=github.com/quickfixgo/quickfix/gen ../spec/$(shell echo $(FIX_TEST) | tr '[:lower:]' '[:upper:]').xml;
28+
# ---------------------------------------------------------------
29+
# Targets related to running acceptance tests -
6430

31+
build-test-srv:
32+
cd _test; go build -o echo_server ./test-server/
6533
fix40:
6634
cd _test; ./runat.sh $@.cfg 5001 "definitions/server/$@/*.def"
6735
fix41:
@@ -83,3 +51,20 @@ ACCEPT_SUITE=fix40 fix41 fix42 fix43 fix44 fix50 fix50sp1 fix50sp2
8351
accept: $(ACCEPT_SUITE)
8452

8553
.PHONY: test $(ACCEPT_SUITE)
54+
# ---------------------------------------------------------------
55+
56+
# ---------------------------------------------------------------
57+
# These targets are specific to the Github CI Runner -
58+
59+
build-src:
60+
go build -v `go list ./...`
61+
62+
build: build-src build-test-srv
63+
64+
test-ci:
65+
go test -v -cover . ./datadictionary ./internal
66+
67+
generate-ci: clean
68+
mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -pkg-root=github.com/quickfixgo/quickfix/gen ../spec/$(shell echo $(FIX_TEST) | tr '[:lower:]' '[:upper:]').xml;
69+
70+
# ---------------------------------------------------------------

README.md

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
QuickFIX/Go
2-
===========
1+
# QuickFIX/Go
32

43
[![Build Status](https://github.com/quickfixgo/quickfix/workflows/CI/badge.svg)](https://github.com/quickfixgo/quickfix/actions) [![GoDoc](https://godoc.org/github.com/quickfixgo/quickfix?status.png)](https://godoc.org/github.com/quickfixgo/quickfix) [![Go Report Card](https://goreportcard.com/badge/github.com/quickfixgo/quickfix)](https://goreportcard.com/report/github.com/quickfixgo/quickfix)
54

@@ -8,29 +7,28 @@ QuickFIX/Go
87

98
Open Source [FIX Protocol](http://www.fixprotocol.org/) library implemented in Go
109

11-
Getting Started and Documentation
12-
---------------------------------
10+
## Getting Started and Documentation
1311

1412
* [User Manual](http://quickfixgo.org/docs)
1513
* [API Documentation](https://godoc.org/github.com/quickfixgo/quickfix)
1614

17-
### Installation
15+
## Installation
1816

1917
To install QuickFIX/Go, use `go get`:
2018

2119
```sh
22-
$ go get github.com/quickfixgo/quickfix
20+
go get github.com/quickfixgo/quickfix
2321
```
2422

25-
### Staying up to date
23+
## Staying up to date
2624

2725
To update QuickFIX/Go to the latest version, use `go get -u github.com/quickfixgo/quickfix`.
2826

29-
### Example Apps
27+
## Example Apps
3028

3129
See [examples](https://github.com/quickfixgo/examples) for some simple examples of using QuickFIX/Go.
3230

33-
### FIX Message Generation
31+
## FIX Message Generation
3432

3533
QuickFIX/Go includes separate packages for tags, fields, enums, messages, and message components generated from the FIX 4.0 - FIX5.0SP2 specs. See:
3634

@@ -51,14 +49,17 @@ For most FIX applications, these generated resources are sufficient. Custom FIX
5149

5250
Following installation, `generate-fix` is installed to `$GOPATH/bin/generate-fix`. Run `$GOPATH/bin/generate-fix --help` for usage instructions.
5351

54-
Developing QuickFIX/Go
55-
----------------------
52+
## Developing QuickFIX/Go
5653

57-
If you wish to work on QuickFIX/Go itself, you will first need [Go](http://www.golang.org) installed and configured on your machine (version 1.13+ is preferred, but the minimum required version is 1.6).
54+
If you wish to work on QuickFIX/Go itself, you will need [Docker](https://docs.docker.com/get-docker/) and [VSCode](https://code.visualstudio.com/download) on your machine.
5855

59-
Next, using [Git](https://git-scm.com/), clone the repository via `git clone [email protected]:quickfixgo/quickfix.git`
56+
* Clone the repo and open it with VSCode with Docker running
57+
* This repo comes with vscode devcontainer configs in `./.devcontainer/`
58+
* Click the pop-up to re-open the project in the Dev Container
59+
* This opens the project in a docker container pre-configured with everything you need
6060

61-
### Installing Dependencies
61+
62+
## Installing Dependencies
6263

6364
As of Go version 1.13, QuickFIX/Go uses [modules](https://github.com/golang/go/wiki/Modules) to manage dependencies. You may require `GO111MODULE=on`. To install dependencies, run
6465

@@ -68,48 +69,50 @@ go mod download
6869

6970
**Note:** No vendored dependencies are included in the QuickFIX/Go source.
7071

71-
### Build and Test
72+
## Build and Test
7273

7374
The default make target runs [go vet](https://godoc.org/golang.org/x/tools/cmd/vet) and unit tests.
7475

7576
```sh
76-
$ make
77+
make
7778
```
7879

7980
If this exits with exit status 0, then everything is working!
8081

81-
### Generated Code
82+
## Generated Code
8283

8384
Generated code from the FIX40-FIX50SP2 specs are available as separate repos under the [QuickFIX/Go organization](https://github.com/quickfixgo). The source specifications for this generated code is located in `spec/`. Generated code can be identified by the `.generated.go` suffix. Any changes to generated code must be captured by changes to source in `cmd/generate-fix`. After making changes to the code generator source, run the following to re-generate the source
8485

8586
```sh
86-
$ make generate-dist
87+
make generate
8788
```
8889

8990
If you are making changes to the generated code, please create Pull Requests for these changes for the affected repos.
9091

91-
### Acceptance Tests
92+
## Acceptance Tests
9293

9394
QuickFIX/Go has a comprehensive acceptance test suite covering the FIX protocol. These are the same tests used across all QuickFIX implementations.
9495

95-
QuickFIX/Go acceptance tests depend on ruby in path.
96+
QuickFIX/Go acceptance tests depend on ruby in path, if you are using the dev container, it is already installed
9697

9798
To run acceptance tests,
9899

99-
# generate code locally
100-
make generate
100+
```sh
101+
# generate code locally
102+
make generate
101103

102-
# build acceptance test rig
103-
make build-test-srv
104+
# build acceptance test rig
105+
make build-test-srv
104106

105-
# run acceptance tests
106-
make accept
107+
# run acceptance tests
108+
make accept
109+
```
107110

108-
### Dependencies
111+
## Dependencies
109112

110113
If you are developing QuickFIX/Go, there are a few tasks you might need to perform related to dependencies.
111114

112-
#### Adding/updating a dependency
115+
### Adding/updating a dependency
113116

114117
If you are adding or updating a dependency, you will need to update the `go.mod` and `go.sum` in the same Pull Request as the code that depends on it. You should do this in a separate commit from your code, as this makes PR review easier and Git history simpler to read in the future.
115118

cmd/generate-fix/generate-fix.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ func main() {
122122
usage()
123123
}
124124

125-
126125
args := flag.Args()
127126
if len(args) == 1 {
128127
dictpath := args[0]

cmd/generate-fix/internal/template_helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func checkIfTimeImportRequiredForFields(fTypes []*datadictionary.FieldType) (ok
3434
if vt, err = quickfixValueType(t); err != nil {
3535
return
3636
}
37-
37+
3838
if vt == "time.Time" {
3939
return true, nil
4040
}

config/configuration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const (
5555
SQLStoreConnMaxLifetime string = "SQLStoreConnMaxLifetime"
5656
MongoStoreConnection string = "MongoStoreConnection"
5757
MongoStoreDatabase string = "MongoStoreDatabase"
58+
MongoStoreReplicaSet string = "MongoStoreReplicaSet"
5859
ValidateFieldsOutOfOrder string = "ValidateFieldsOutOfOrder"
5960
ResendRequestChunkSize string = "ResendRequestChunkSize"
6061
EnableLastMsgSeqNumProcessed string = "EnableLastMsgSeqNumProcessed"

config/doc.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ MongoStoreDatabase
363363
364364
The MongoDB-specific name of the database to use. Only used with MongoStoreFactory.
365365
366+
MongoStoreReplicaSet
367+
368+
The MongoDB-specific name of the replica set to use. Optional, only used with MongoStoreFactory.
369+
366370
SQLStoreDriver
367371
368372
The name of the database driver to use (see https://github.com/golang/go/wiki/SQLDrivers for the list of available drivers). Only used with SqlStoreFactory.

filestore.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,6 @@ func (store *fileStore) SaveMessage(seqNum int, msg []byte) error {
287287
return fmt.Errorf("unable to write to file: %s: %s", store.headerFname, err.Error())
288288
}
289289

290-
store.offsets[seqNum] = msgDef{offset: offset, size: len(msg)}
291-
292290
if _, err := store.bodyFile.Write(msg); err != nil {
293291
return fmt.Errorf("unable to write to file: %s: %s", store.bodyFname, err.Error())
294292
}
@@ -298,9 +296,19 @@ func (store *fileStore) SaveMessage(seqNum int, msg []byte) error {
298296
if err := store.headerFile.Sync(); err != nil {
299297
return fmt.Errorf("unable to flush file: %s: %s", store.headerFname, err.Error())
300298
}
299+
300+
store.offsets[seqNum] = msgDef{offset: offset, size: len(msg)}
301301
return nil
302302
}
303303

304+
func (store *fileStore) SaveMessageAndIncrNextSenderMsgSeqNum(seqNum int, msg []byte) error {
305+
err := store.SaveMessage(seqNum, msg)
306+
if err != nil {
307+
return err
308+
}
309+
return store.IncrNextSenderMsgSeqNum()
310+
}
311+
304312
func (store *fileStore) getMessage(seqNum int) (msg []byte, found bool, err error) {
305313
msgInfo, found := store.offsets[seqNum]
306314
if !found {

0 commit comments

Comments
 (0)