dynflow 1.6.2 → 1.6.3

Sign up to get free protection for your applications and to get access to all the features.
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