dynflow 1.6.2 → 1.6.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0e5c6a8141eaea583bebabd135cdbfcff6c2516410db7930595e3868383f331
4
- data.tar.gz: bc72a36dd5284f5cea95651de2620f0d41db5f315195a4ed573155c94b510bb9
3
+ metadata.gz: 40e7ab36f1ef2943d1cbebccde747a2c89186a620493a74bfefb06a810e8bf13
4
+ data.tar.gz: c2d4da5a39382f4df50ac0a1664edab9b772f94fc6da4f7f5eec51c24b91e256
5
5
  SHA512:
6
- metadata.gz: c9b0efe531cf9d3c45432bfc94542f47ff6a72fe20bd96a4541242f58a13abc77603a62fcb5294e481feb9a28c49c6eebd2a9747092da6fe7a5e67ad1dc8e9d3
7
- data.tar.gz: d9c66e79fad07d6e6bfb9b8e265af0062adf8ba2b0d8d126e46080ca890200db07346f7c4702518a9c4d4ace4ae94d668ce20761166c9e81a7ef5531cdc85240
6
+ metadata.gz: 955818d3401e8641df7ad06ad0307791502437ac3b2549dee9d1161c8dd29d76e83f03b378b6c451547d2e1a00f0b8bbdfa282ea9b6e3fc37005e1fde59ebff6
7
+ data.tar.gz: 2cb868cab752e95928521d1276bca3091f3ebbd55437e80a82baf980c636880dea3bdb3b345252e2735ffe236960c9d9c6d78a471acc9462c8341581ec91ff98
@@ -0,0 +1,48 @@
1
+ # workflow name
2
+ name: Generate release-artifacts
3
+
4
+ # on events
5
+ on:
6
+ push:
7
+ tags:
8
+ - '*'
9
+
10
+ # workflow tasks
11
+ jobs:
12
+ generate:
13
+ name: Generate build artifacts
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: olegtarasov/get-tag@v2.1
17
+ id: tagName
18
+ with:
19
+ tagRegex: "v(.*)" # Optional. Returns specified group text as tag name. Full tag string is returned if regex is not defined.
20
+ tagRegexGroup: 1 # Optional. Default is 1.
21
+ - name: Checkout the repository
22
+ uses: actions/checkout@v2
23
+ - name: Generate build files
24
+ run: |
25
+ mkdir -p dist
26
+ cd extras/expand
27
+ go build -o ../../dist/dynflow-expand-${VERSION}-x86_64
28
+ env:
29
+ VERSION: '${{ steps.tagName.outputs.tag }}'
30
+ - name: Generate distribution tarball
31
+ run: |
32
+ cd extras/expand
33
+ go mod vendor
34
+ tar --create \
35
+ --gzip \
36
+ --file ../../dist/dynflow-expand-${VERSION}.tar.gz \
37
+ --transform s/^\./dynflow-expand-${VERSION}/ \
38
+ .
39
+ env:
40
+ VERSION: '${{ steps.tagName.outputs.tag }}'
41
+ - name: Upload binaries to release
42
+ uses: svenstaro/upload-release-action@v2
43
+ with:
44
+ repo_token: ${{ secrets.GITHUB_TOKEN }}
45
+ file: dist/*
46
+ tag: ${{ github.ref }}
47
+ overwrite: true
48
+ file_glob: true
data/Gemfile CHANGED
@@ -35,7 +35,7 @@ end
35
35
 
36
36
  group :rails do
37
37
  gem 'daemons'
38
- gem 'rails', '>= 4.2.9'
38
+ gem 'rails', '>= 4.2.9', '< 7'
39
39
  gem 'logging'
40
40
  end
41
41
 
@@ -0,0 +1,9 @@
1
+ FROM alpine:3.15 as builder
2
+ RUN apk add -U go
3
+ ADD ./ work/
4
+ RUN cd /work && \
5
+ go build
6
+
7
+ FROM scratch
8
+ COPY --from=builder /work/expand /expand
9
+ CMD ["/expand"]
@@ -0,0 +1,25 @@
1
+ # expand
2
+
3
+ For a long time, Dynflow's database schema remained stable. To optimize Dynflow
4
+ a bit, we started changing it. One of the changes was changing how we encode
5
+ flows, resulting in flows taking roughly 10x less space.
6
+
7
+ The other change is not merged yet, but has potentionally bigger impact. We
8
+ store certain columns as JSON objects. The upcoming change uses msgpack instead
9
+ of JSON, resulting in faster encoding and decoding times and smaller storage
10
+ footprint when encoded. The drawback is it is a binary format, so if someone
11
+ dumps the tables from DB as CSV, they won't be human readable.
12
+
13
+ This tool processes CSV DB dumps and decodes msgpack to json.
14
+
15
+ ## Usage
16
+
17
+ ```shell
18
+ # cat dynflow_execution_plans.csv
19
+ 2065cc55-6b03-44b7-947a-e999dcb9057f,,stopped,error,,2021-04-16 09:50:33.826,0,0,,Dynflow::ExecutionPlan,1,\x91a143,\x91a153,\x9283a474696d65ce60795de9a46e616d65a564656c6179a8776f726c645f6964d92435626536643435662d363732342d343666652d393035662d34363565316466346561306183a474696d65ce60795de9a46e616d65a774696d656f7574a8776f726c645f6964d92435626536643435662d363732342d343666652d393035662d343635653164663465613061,\x9101
20
+ 6667374a-beab-4b0b-80c8-3d0392cdde40,,scheduled,pending,,,0,,,Dynflow::ExecutionPlan,1,\x91a143,\x91a153,\x9183a474696d65ce60795de9a46e616d65a564656c6179a8776f726c645f6964d92435626536643435662d363732342d343666652d393035662d343635653164663465613061,\x9101
21
+
22
+ # expand < dynflow_execution_plans.csv
23
+ 2065cc55-6b03-44b7-947a-e999dcb9057f,,stopped,error,,2021-04-16 09:50:33.826,0,0,,Dynflow::ExecutionPlan,1,"[""C""]","[""S""]","[{""name"":""delay"",""time"":1618566633,""world_id"":""5be6d45f-6724-46fe-905f-465e1df4ea0a""},{""name"":""timeout"",""time"":1618566633,""world_id"":""5be6d45f-6724-46fe-905f-465e1df4ea0a""}]",[1]
24
+ 6667374a-beab-4b0b-80c8-3d0392cdde40,,scheduled,pending,,,0,,,Dynflow::ExecutionPlan,1,"[""C""]","[""S""]","[{""name"":""delay"",""time"":1618566633,""world_id"":""5be6d45f-6724-46fe-905f-465e1df4ea0a""}]",[1]
25
+ ```
@@ -0,0 +1,5 @@
1
+ module github.com/dynflow/dynflow/expand
2
+
3
+ go 1.15
4
+
5
+ require github.com/vmihailenco/msgpack/v5 v5.3.5
@@ -0,0 +1,11 @@
1
+ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2
+ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3
+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
4
+ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
5
+ github.com/vmihailenco/msgpack v3.3.3+incompatible h1:wapg9xDUZDzGCNFlwc5SqI1rvcciqcxEHac4CYj89xI=
6
+ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
7
+ github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
8
+ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
9
+ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
10
+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
11
+ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -4,47 +4,17 @@ import (
4
4
  "encoding/csv"
5
5
  "encoding/hex"
6
6
  "encoding/json"
7
- "github.com/vmihailenco/msgpack"
7
+ "github.com/vmihailenco/msgpack/v5"
8
8
  "io"
9
9
  "os"
10
10
  )
11
11
 
12
- // dynflow_steps
13
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
14
- // execution_plan_uuid,id,action_id,data,state,started_at,ended_at,real_time,execution_time,progress_done,progress_weight,class,error,action_class,children,queue
15
- //
16
- // encoded columns are:
17
- // 3 - data
18
- // 12 - error
19
- // 14 - children
20
-
21
- // dynflow_actions
22
- // 0 1 2 3 4 5 6 7 8 9 10
23
- // execution_plan_uuid,id,data,caller_execution_plan_id,caller_action_id,class,input,output,plan_step_id,run_step_id,finalize_step_id
24
- //
25
- // encoded columns are:
26
- // 2 - data
27
- // 6 - input
28
- // 7 - output
29
-
30
- // dynflow_execution_plans
31
- // Without msgpack
32
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
33
- // uuid,data,state,result,started_at,ended_at,real_time,execution_time,label,class,run_flow,finalize_flow,execution_history,root_plan_step_id,step_ids
34
-
35
- // With msgpack
36
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
37
- // uuid,data,state,result,started_at,ended_at,real_time,execution_time,label,class,root_plan_step_id,run_flow,finalize_flow,execution_history,step_ids
38
- //
39
- // 1 - data
40
- // 11 - run_flow
41
- // 12 - finalize_flow
42
- // 13 - execution_history
43
- // 14 - step_ids
44
-
45
12
  func main() {
46
13
  reader := csv.NewReader(os.Stdin)
14
+ defer os.Stdin.Close()
15
+
47
16
  writer := csv.NewWriter(os.Stdout)
17
+ defer os.Stdout.Close()
48
18
  defer writer.Flush()
49
19
 
50
20
  for {
@@ -58,31 +28,12 @@ func main() {
58
28
  }
59
29
 
60
30
  func processRow(record []string) []string {
61
- // Execution plan exports have 15 fields, other exports have different counts
62
- if len(record) == 15 {
63
- record = expandExecutionPlan(record)
64
- }
65
-
66
31
  for i, r := range record {
67
- record[i] = reencodeField(r)
68
- }
69
-
70
- return record
71
- }
72
-
73
- func expandExecutionPlan(record []string) []string {
74
- var flow_columns [2]int
75
-
76
- // The step_ids field should be a safe indicator
77
- if isHexEncoded(record[14]) {
78
- flow_columns = [...]int{11, 12}
79
- } else {
80
- flow_columns = [...]int{10, 11}
32
+ if isHexEncoded(r) {
33
+ record[i] = reencodeField(r)
34
+ }
81
35
  }
82
36
 
83
- for _, i := range flow_columns {
84
- record[i] = expandFlow(record[i])
85
- }
86
37
  return record
87
38
  }
88
39
 
@@ -91,38 +42,18 @@ func isHexEncoded(field string) bool {
91
42
  }
92
43
 
93
44
  func reencodeField(field string) string {
94
- decoded, err := decode(field)
45
+ decoded_bytes, err := hex.DecodeString(field[2:])
95
46
  if err != nil {
96
47
  return field
97
48
  }
98
49
 
99
- return encode(decoded)
100
- }
101
-
102
- func decode(field string) (interface{}, error) {
103
50
  var intermediate interface{}
104
- bytes := []byte(field)
105
-
106
- if isHexEncoded(field) {
107
- decoded_bytes, err := hex.DecodeString(field[2:])
108
- if err != nil {
109
- return "", err
110
- }
111
-
112
- err = msgpack.Unmarshal(decoded_bytes, &intermediate)
113
- if err != nil {
114
- return "", err
115
- }
116
-
117
- return intermediate, nil
118
- }
119
-
120
- err := json.Unmarshal(bytes, &intermediate)
51
+ err = msgpack.Unmarshal(decoded_bytes, &intermediate)
121
52
  if err != nil {
122
- return "", err
53
+ return field
123
54
  }
124
55
 
125
- return intermediate, nil
56
+ return encode(intermediate)
126
57
  }
127
58
 
128
59
  func encode(data interface{}) string {
@@ -133,48 +64,3 @@ func encode(data interface{}) string {
133
64
 
134
65
  return string(result)
135
66
  }
136
-
137
- func expandFlow(field string) string {
138
- intermediate, err := decode(field)
139
- if err != nil {
140
- return field
141
- }
142
-
143
- var result map[string]interface{}
144
- switch intermediate.(type) {
145
- // old style hash
146
- case map[string]interface{}:
147
- result = intermediate.(map[string]interface{})
148
- // newer compact S-expression like representation
149
- case []interface{}, float64:
150
- result = expandCompactFlow(intermediate)
151
- }
152
-
153
- return encode(result)
154
- }
155
-
156
- func expandCompactFlow(flow interface{}) map[string]interface{} {
157
- result := make(map[string]interface{})
158
- switch flow.(type) {
159
- case []interface{}:
160
- switch flow.([]interface{})[0] {
161
- case "S":
162
- result["class"] = "Dynflow::Flows::Sequence"
163
- case "C":
164
- result["class"] = "Dynflow::Flows::Concurrence"
165
- default:
166
- panic("Unknown flow type")
167
- }
168
- var subflows []interface{}
169
- for subflow := range flow.([]interface{})[1:] {
170
- subflows = append(subflows, expandCompactFlow(subflow))
171
- }
172
- result["flows"] = subflows
173
- case float64, int:
174
- result["class"] = "Dynflow::Flows::Atom"
175
- result["step_id"] = flow
176
- default:
177
- panic("Unknown flow type")
178
- }
179
- return result
180
- }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'multi_json'
3
+ require 'json'
4
4
  require 'msgpack'
5
5
 
6
6
  def table_pkeys(table)
@@ -74,7 +74,7 @@ Sequel.migration do
74
74
  new_columns = columns.map { |c| "#{c}_blob" }
75
75
 
76
76
  migrate_table table, columns, new_columns, File do |data|
77
- ::Sequel.blob(MessagePack.pack(MultiJson.load(data)))
77
+ ::Sequel.blob(MessagePack.pack(JSON.parse(data)))
78
78
  end
79
79
  end
80
80
  end
@@ -83,7 +83,7 @@ Sequel.migration do
83
83
  TABLES.each do |table, columns|
84
84
  new_columns = columns.map { |c| c + '_text' }
85
85
  migrate_table table, columns, new_columns, String do |data|
86
- MultiJson.dump(MessagePack.unpack(data))
86
+ JSON.dump(MessagePack.unpack(data))
87
87
  end
88
88
  end
89
89
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Dynflow
3
- VERSION = '1.6.2'
3
+ VERSION = '1.6.3'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Necas
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-12-10 00:00:00.000000000 Z
12
+ date: 2022-01-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
@@ -263,6 +263,7 @@ extensions: []
263
263
  extra_rdoc_files: []
264
264
  files:
265
265
  - ".github/install_dependencies.sh"
266
+ - ".github/workflows/release.yml"
266
267
  - ".github/workflows/ruby.yml"
267
268
  - ".gitignore"
268
269
  - ".rubocop.yml"
@@ -419,6 +420,10 @@ files:
419
420
  - examples/sub_plan_concurrency_control.rb
420
421
  - examples/sub_plans.rb
421
422
  - examples/termination.rb
423
+ - extras/expand/Dockerfile
424
+ - extras/expand/README.md
425
+ - extras/expand/go.mod
426
+ - extras/expand/go.sum
422
427
  - extras/expand/main.go
423
428
  - extras/statsd_mapping.conf
424
429
  - lib/dynflow.rb