Skip to content

Commit 170d289

Browse files
authored
Improved the cancellation propagation and added more documentation (#6)
1 parent a592721 commit 170d289

File tree

697 files changed

+66045
-996
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

697 files changed

+66045
-996
lines changed

.golangci.yaml

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@ run:
22
# Timeout for analysis, e.g. 30s, 5m.
33
timeout: 3m
44

5-
# Don't lint the vendor directory
6-
skip-dirs:
7-
- ^vendor$
8-
95
# Fail if the error was met.
106
issues-exit-code: 1
117

@@ -19,11 +15,6 @@ run:
1915
build-tags:
2016
- integration
2117

22-
# When enabled linter will skip directories: vendor$, third_party$,
23-
# testdata$, examples$, Godeps$, builtin$ Skipping `examples` sounds scary
24-
# to me but skipping `testdata` sounds ok.
25-
skip-dirs-use-default: false
26-
2718
# With the read-only mode linter will fail if go.mod file is outdated.
2819
modules-download-mode: readonly
2920

@@ -45,12 +36,11 @@ linters:
4536
- asciicheck # checks that your code does not contain non-ASCII identifiers
4637
- bidichk # checks for dangerous unicode character sequences
4738
- bodyclose # checks whether HTTP response body is closed successfully
48-
- cyclop # checks function and package cyclomatic complexity
39+
# - cyclop # checks function and package cyclomatic complexity
4940
- dupl # tool for code clone detection
5041
- durationcheck # checks for two durations multiplied together
5142
- errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error
5243
- errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13
53-
- execinquery # checks query string in Query function which reads your Go src files and warning it finds
5444
- exhaustive # checks exhaustiveness of enum switch statements
5545
- exportloopref # checks for pointers to enclosing loop variables
5646
- forbidigo # forbids identifiers
@@ -69,7 +59,6 @@ linters:
6959
- gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations
7060
- goprintffuncname # checks that printf-like functions are named with f at the end
7161
- gosec # inspects source code for security problems
72-
- lll # reports long lines
7362
- loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap)
7463
- makezero # finds slice declarations with non-zero initial length
7564
- mirror # reports wrong mirror patterns of bytes/strings usage
@@ -101,15 +90,13 @@ linters:
10190
- usestdlibvars # detects the possibility to use variables/constants from the Go standard library
10291
- wastedassign # finds wasted assignment statements
10392
- whitespace # detects leading and trailing whitespace
104-
- contextcheck # Check whether the function uses a non-inherited context.
10593
- misspell # finds commonly misspelled English words in comments
10694
- prealloc # can be used to find slice declarations that could potentially be preallocated
10795
- thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers
10896
- containedctx # detects struct contained context.Context field
10997
- decorder # checks declaration order and count of types, constants, variables and functions
11098
- dogsled # checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
111-
# - exhaustruct # [highly recommend to enable] checks if all structure fields are initialized
112-
- nlreturn # checks for a new line before return and branch statements to increase code clarity
99+
- paralleltest # detects missing usage of t.Parallel() method in your Go test
113100

114101
## you may want to enable
115102
#- gci # controls golang package import order and makes it always deterministic
@@ -123,8 +110,11 @@ linters:
123110
#- varnamelen # [great idea, but too many false positives] checks that the length of a variable's name matches its scope
124111
#- wrapcheck # checks that errors returned from external packages are wrapped
125112
#- zerologlint # detects the wrong usage of zerolog that a user forgets to dispatch zerolog.Event
113+
# - nlreturn # checks for a new line before return and branch statements to increase code clarity
126114

127115
## disabled
116+
# - lll # reports long lines
117+
# - exhaustruct # [highly recommend to enable] checks if all structure fields are initialized
128118
#- depguard # [replaced by gomodguard] checks if package imports are in a list of acceptable packages
129119
#- dupword # [useless without config] checks for duplicate words in the source code
130120
#- errchkjson # [don't see profit + I'm against of omitting errors like in the first example https://github.com/breml/errchkjson] checks types passed to the json encoding functions. Reports unsupported types and optionally reports occasions, where the check for the returned error can be omitted
@@ -136,13 +126,15 @@ linters:
136126
#- grouper # analyzes expression groups
137127
#- importas # enforces consistent import aliases
138128
#- maintidx # measures the maintainability index of each function
139-
#- paralleltest # [too many false positives] detects missing usage of t.Parallel() method in your Go test
140129
#- wsl # [too strict and mostly code is not more readable] whitespace linter forces you to use empty lines
141130
#- tagliatelle # checks the struct tags
131+
#- contextcheck # Check whether the function uses a non-inherited context.
142132

143133
# This file contains only configs which differ from defaults.
144134
# All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml
145135
linters-settings:
136+
nestif:
137+
min-complexity: 8
146138
cyclop:
147139
# The maximal code complexity to report.
148140
# Default: 10
@@ -168,7 +160,7 @@ linters-settings:
168160
- map
169161

170162
nlreturn:
171-
block-size: 120
163+
block-size: 8
172164

173165
exhaustruct:
174166
# Default: []
@@ -202,18 +194,19 @@ linters-settings:
202194
# Checks the number of lines in a function.
203195
# If lower than 0, disable the check.
204196
# Default: 60
205-
lines: 100
197+
lines: 150
206198
# Checks the number of statements in a function.
207199
# If lower than 0, disable the check.
208200
# Default: 40
209-
statements: 50
201+
statements: 60
210202
# Ignore comments when counting lines.
211203
# Default false
212204
ignore-comments: true
213205

214206
gocognit:
215207
# Minimal code complexity to report.
216-
min-complexity: 30
208+
# Default: 30 (but we recommend 10-20)
209+
min-complexity: 70
217210

218211
gocritic:
219212
# Settings passed to gocritic.
@@ -256,12 +249,6 @@ linters-settings:
256249
# Default: []
257250
disable:
258251
- fieldalignment # too strict
259-
# Settings per analyzer.
260-
settings:
261-
shadow:
262-
# Whether to be strict about shadowing; can be noisy.
263-
# Default: false
264-
strict: true
265252

266253
nakedret:
267254
# Make an issue if func has more lines of code than this setting, and it has naked returns.
@@ -297,6 +284,15 @@ issues:
297284
# Default: 3
298285
max-same-issues: 50
299286

287+
# Don't lint the vendor or example directories.
288+
exclude-dirs:
289+
- ^vendor$
290+
- examples
291+
292+
# When enabled, the following directories: are going to be skipped: vendor$,
293+
# third_party$, testdata$, examples$, Godeps$, builtin$.
294+
exclude-dirs-use-default: false
295+
300296
exclude-rules:
301297
- source: "(noinspection|TODO)"
302298
linters: [godot]
@@ -312,6 +308,5 @@ issues:
312308
- noctx
313309
- wrapcheck
314310
- exhaustruct
315-
- path: "client"
316-
linters:
311+
- unparam
317312
- errcheck

.goreleaser.yaml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
before:
2+
hooks:
3+
- go mod tidy
4+
builds:
5+
- main: ./cmd/server
6+
binary: server
7+
env:
8+
- CGO_ENABLED=0
9+
goos:
10+
- linux
11+
- darwin
12+
goarch:
13+
- arm64
14+
- amd64
15+
- 386
16+
output:
17+
dir: dist/{{ .Os }}/{{ .Arch }}
18+
19+
- main: ./cmd/client
20+
binary: client
21+
env:
22+
- CGO_ENABLED=0
23+
goos:
24+
- linux
25+
- darwin
26+
goarch:
27+
- amd64
28+
- 386
29+
output:
30+
dir: dist/{{ .Os }}/{{ .Arch }}
31+
32+
archives:
33+
- format: tar.gz
34+
name_template: >-
35+
{{ .ProjectName }}_
36+
{{- title .Os }}_
37+
{{- if eq .Arch "amd64" }}x86_64
38+
{{- else if eq .Arch "386" }}i386
39+
{{- else }}{{ .Arch }}{{ end }}
40+
{{- if .Arm }}v{{ .Arm }}{{ end }}
41+
checksum:
42+
name_template: 'checksums.txt'
43+
snapshot:
44+
name_template: "{{ incpatch .Version }}-next"
45+
changelog:
46+
sort: asc
47+
filters:
48+
exclude:
49+
- '^docs:'
50+
- '^test:'
51+
52+
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
53+
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

Makefile

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# Include variables from the .envrc file
2-
include .envrc
3-
41
.DEFAULT_GOAL := build
52

63
# ==================================================================================== #
@@ -36,19 +33,18 @@ test: test
3633
@echo 'Removing test cache...'
3734
go clean -testcache
3835
@echo 'Running tests...'
39-
go test -race -vet=off -timeout 30s ./...
36+
go test -race -vet=off -timeout 10s ./...
4037

4138

4239
## audit: tidy and vendor dependencies and format, vet and test all code
40+
.PHONY: audit
4341
audit: vendor
4442
@echo 'Formatting code...'
4543
go fmt ./...
46-
@echo 'Vetting code...'
47-
go vet ./...
48-
staticcheck ./...
44+
@echo 'Linting code...'
45+
golangci-lint run
4946
@echo 'Running tests...'
5047
go test -race -vet=off ./...
51-
.PHONY:audit
5248

5349
## vendor: tidy and vendor dependencies
5450
vendor:

README.md

Lines changed: 96 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,108 @@ on my [website][1]
1313
![Screenshot of website][3]
1414

1515
# How it works
16+
1617
After spending some time debugging different language servers in Neovim, I felt
1718
inspired to write my own server that would simply parse metadata and aggregate
18-
statistics about my coding sessions so that I could display it on my website.
19+
statistics about my coding sessions.
1920

20-
I launch the server from this repository as a daemon every time my laptop
21-
boots. It then receives remote procedure calls from the neovim plugin
22-
pertaining to events such as the opening of buffers, windows gaining focus, the
23-
initiation of new `nvim` processes, etc.
21+
I run the server from this repository as a daemon, and it receives remote
22+
procedure calls from the neovim plugin pertaining to events such as the opening
23+
of buffers, windows gaining focus, the initiation of new `nvim` processes, etc.
2424

2525
These calls contains the path to the buffer, which the server parses and writes
26-
to an append-only log-structured key-value store. Every segment is roughly 10KB
27-
on disk. The server requests all of the buffers from this KV store every 15
28-
minutes, and proceeds to aggregate them to a remote MongoDB database.
29-
30-
I chose this approach primarily because I wanted to build a log-structured
31-
storage engine in order to better understand the inner workings of some popular
32-
databases. It is a work in progress, but it now includes some core features
33-
such as hash indexes, segmentation, and compaction. As a bonus, it helps me
34-
avoid surpassing the limits set by the free tier for the MongoDB database!
35-
36-
This project has evolved into a playground where I can experiment with
37-
different ideas and technologies. The most challenging part so far has been
38-
designing the website, as I wanted it to have a unique look and feel and to
39-
build all of the components from scratch. I'm in the process of making it open
40-
source, but I have a few things that I'd like to clean up first.
26+
to a log-structured key-value store. The store is a work in progress, but it
27+
now includes some core features such as hash indexes, segmentation, and
28+
compaction.
29+
30+
The server runs a background job which requests all of the buffers from the KV
31+
store, and proceeds to aggregate them to a remote database. I chose this
32+
approach primarily because I wanted to avoid surpassing the limits set by the
33+
free tier for the MongoDB database.
34+
35+
The only things that aren't included in this repository is the API which
36+
retrieves the data and the website that displays it. The website has been the
37+
most challenging part so far because I wanted it to have a unique look and feel
38+
and to build all of the components from scratch. I'm in the process of making
39+
it open source, but there are still a few things that I'd like to clean up
40+
first.
41+
42+
# Running this project
43+
44+
## 1. Download the binaries
45+
Download and unpack the server and client binaries from the [releases](https://github.com/creativecreature/sturdyc/releases).
46+
Next, you'll want to make sure that they are reachable from your `$PATH`.
47+
48+
## 2. Create a configuration file
49+
Create a configuration file. It should be located at `$HOME/.pulse/config.yaml`
50+
51+
```yml
52+
server:
53+
name: "pulse-server"
54+
hostname: "localhost"
55+
port: "1122"
56+
aggregationInterval: "10m"
57+
segmentationInterval: "5m"
58+
database:
59+
uri: "mongodb+srv://<USERNAME>:[email protected]/?retryWrites=true"
60+
name: "pulse"
61+
collection: "sessions"
62+
```
63+
64+
## 3. Launch the server as a daemon
65+
On linux, you can setup a systemd service to run the server, and on macOS you
66+
can create a launch daemon.
67+
68+
I'm using a Mac, and my launch daemon configuration looks like this:
69+
70+
```xml
71+
<?xml version="1.0" encoding="UTF-8"?>
72+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
73+
<plist version="1.0">
74+
<dict>
75+
76+
<key>Label</key>
77+
<string>dev.conner.pulse.plist</string>
78+
79+
<key>RunAtLoad</key>
80+
<true/>
81+
82+
<key>StandardErrorPath</key>
83+
<string>/Users/conner/.pulse/logs/stderr.log</string>
84+
85+
<key>StandardOutPath</key>
86+
<string>/Users/conner/.pulse/logs/stdout.log</string>
87+
88+
<key>EnvironmentVariables</key>
89+
<dict>
90+
<key>PATH</key>
91+
<string><![CDATA[/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin]]></string>
92+
</dict>
93+
94+
<key>WorkingDirectory</key>
95+
<string>/Users/conner</string>
96+
97+
<key>ProgramArguments</key>
98+
<array>
99+
<string>/Users/conner/bin/pulse-server</string>
100+
</array>
101+
102+
<key>KeepAlive</key>
103+
<true/>
104+
105+
</dict>
106+
</plist>
107+
```
108+
109+
## 4. Install the neovim plugin
110+
Here is an example using lazy.nvim:
41111

112+
```lua
113+
return {
114+
-- Does not require any configuration.
115+
{ "creativecreature/pulse" },
116+
}
117+
```
42118

43119
[1]: https://conner.dev
44120
[2]: ./screenshots/website1.png

0 commit comments

Comments
 (0)