feedx 0.9.2 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +2 -0
  4. data/.travis.yml +13 -6
  5. data/Gemfile.lock +43 -20
  6. data/Makefile +5 -0
  7. data/consumer_test.go +5 -5
  8. data/feedx.gemspec +3 -2
  9. data/feedx_test.go +13 -13
  10. data/format.go +16 -16
  11. data/format_test.go +6 -7
  12. data/go.mod +5 -11
  13. data/go.sum +43 -26
  14. data/internal/testdata/testdata.pb.go +124 -0
  15. data/internal/testdata/testdata.proto +15 -0
  16. data/lib/feedx/cache/abstract.rb +2 -2
  17. data/lib/feedx/compression.rb +11 -4
  18. data/lib/feedx/compression/abstract.rb +2 -2
  19. data/lib/feedx/compression/gzip.rb +14 -2
  20. data/lib/feedx/compression/none.rb +4 -4
  21. data/lib/feedx/consumer.rb +12 -9
  22. data/lib/feedx/format.rb +18 -9
  23. data/lib/feedx/format/abstract.rb +42 -13
  24. data/lib/feedx/format/json.rb +12 -8
  25. data/lib/feedx/format/parquet.rb +102 -0
  26. data/lib/feedx/format/protobuf.rb +16 -8
  27. data/lib/feedx/producer.rb +12 -9
  28. data/lib/feedx/stream.rb +22 -25
  29. data/producer.go +1 -4
  30. data/producer_test.go +1 -2
  31. data/reader_test.go +7 -8
  32. data/spec/feedx/compression/gzip_spec.rb +4 -2
  33. data/spec/feedx/compression/none_spec.rb +2 -2
  34. data/spec/feedx/compression_spec.rb +9 -9
  35. data/spec/feedx/consumer_spec.rb +6 -3
  36. data/spec/feedx/format/abstract_spec.rb +11 -8
  37. data/spec/feedx/format/json_spec.rb +12 -11
  38. data/spec/feedx/format/parquet_spec.rb +30 -0
  39. data/spec/feedx/format/protobuf_spec.rb +12 -11
  40. data/spec/feedx/format_spec.rb +8 -8
  41. data/spec/feedx/producer_spec.rb +6 -0
  42. data/spec/feedx/stream_spec.rb +20 -1
  43. data/spec/spec_helper.rb +17 -1
  44. data/writer.go +19 -18
  45. data/writer_test.go +3 -5
  46. metadata +22 -3
@@ -64,4 +64,10 @@ RSpec.describe Feedx::Producer do
64
64
  size = described_class.perform 'mock:///dir/file.json', last_modified: Time.at(1515151516), enum: enumerable
65
65
  expect(size).to eq(15900)
66
66
  end
67
+
68
+ it 'should accept downstream options' do
69
+ expect do
70
+ described_class.perform 'mock:///dir/file.jsonz', enum: enumerable, x: 1, y: 'v', z: true
71
+ end.not_to raise_error
72
+ end
67
73
  end
@@ -13,13 +13,32 @@ RSpec.describe Feedx::Stream do
13
13
  end.to raise_error(/unable to detect format/)
14
14
  end
15
15
 
16
+ it 'should accept custom formats' do
17
+ format = Class.new do
18
+ def encoder(io, &block)
19
+ Feedx::Format::JSON::Encoder.open(io, &block)
20
+ end
21
+
22
+ def decoder(io, &block)
23
+ Feedx::Format::JSON::Decoder.open(io, &block)
24
+ end
25
+ end
26
+
27
+ stream = described_class.new('mock:///dir/file.txt', format: format.new)
28
+ stream.create {|s| s.encode Feedx::TestCase::Model.new('X') }
29
+
30
+ expect(bucket.read('dir/file.txt')).to eq(
31
+ %({"title":"X","updated_at":"2018-01-05 11:25:15 UTC"}\n),
32
+ )
33
+ end
34
+
16
35
  it 'should encode' do
17
36
  subject.create do |s|
18
37
  s.encode(Feedx::TestCase::Model.new('X'))
19
38
  s.encode(Feedx::TestCase::Model.new('Y'))
20
39
  end
21
40
 
22
- expect(bucket.open('dir/file.json').read).to eq(
41
+ expect(bucket.read('dir/file.json')).to eq(
23
42
  %({"title":"X","updated_at":"2018-01-05 11:25:15 UTC"}\n) +
24
43
  %({"title":"Y","updated_at":"2018-01-05 11:25:15 UTC"}\n),
25
44
  )
@@ -28,13 +28,29 @@ module Feedx
28
28
  end
29
29
  alias eql? ==
30
30
 
31
+ def updated_at
32
+ Time.at(1515151515).utc
33
+ end
34
+
31
35
  def from_json(data, *)
32
36
  hash = ::JSON.parse(data)
33
37
  @title = hash['title'] if hash.is_a?(Hash)
34
38
  end
35
39
 
36
40
  def to_json(*)
37
- ::JSON.dump(title: @title, updated_at: Time.at(1515151515).utc)
41
+ ::JSON.dump(title: @title, updated_at: updated_at)
42
+ end
43
+
44
+ def from_parquet(rec)
45
+ rec.each_pair do |name, value|
46
+ @title = value if name == 'title'
47
+ end
48
+ end
49
+
50
+ def to_parquet(schema, *)
51
+ schema.fields.map do |field|
52
+ send(field.name)
53
+ end
38
54
  end
39
55
  end
40
56
  end
data/writer.go CHANGED
@@ -3,7 +3,6 @@ package feedx
3
3
  import (
4
4
  "bufio"
5
5
  "context"
6
- "errors"
7
6
  "io"
8
7
  "time"
9
8
 
@@ -40,33 +39,29 @@ func (o *WriterOptions) norm(name string) {
40
39
  // Writer encodes feeds to remote locations.
41
40
  type Writer struct {
42
41
  ctx context.Context
43
- cancel context.CancelFunc
44
-
45
42
  remote *bfs.Object
46
43
  opt WriterOptions
47
44
  num int
48
45
 
49
- bw io.WriteCloser // bfs writer
46
+ bw bfs.Writer
50
47
  cw io.WriteCloser // compression writer
51
48
  ww *bufio.Writer
52
49
  fe FormatEncoder
53
50
  }
54
51
 
55
52
  // NewWriter inits a new feed writer.
56
- func NewWriter(ctx context.Context, remote *bfs.Object, opt *WriterOptions) (*Writer, error) {
53
+ func NewWriter(ctx context.Context, remote *bfs.Object, opt *WriterOptions) *Writer {
57
54
  var o WriterOptions
58
55
  if opt != nil {
59
56
  o = *opt
60
57
  }
61
58
  o.norm(remote.Name())
62
59
 
63
- ctx, cancel := context.WithCancel(ctx)
64
60
  return &Writer{
65
61
  ctx: ctx,
66
- cancel: cancel,
67
62
  remote: remote,
68
63
  opt: o,
69
- }, nil
64
+ }
70
65
  }
71
66
 
72
67
  // Write write raw bytes to the feed.
@@ -114,16 +109,27 @@ func (w *Writer) NumWritten() int {
114
109
 
115
110
  // Discard closes the writer and discards the contents.
116
111
  func (w *Writer) Discard() error {
117
- w.cancel()
118
- if err := w.Commit(); err != nil && !errors.Is(err, context.Canceled) {
119
- return err
112
+ err := w.close()
113
+ if w.bw != nil {
114
+ if e := w.bw.Discard(); e != nil {
115
+ err = e
116
+ }
120
117
  }
121
- return nil
118
+ return err
122
119
  }
123
120
 
124
121
  // Commit closes the writer and persists the contents.
125
122
  func (w *Writer) Commit() error {
126
- var err error
123
+ err := w.close()
124
+ if w.bw != nil {
125
+ if e := w.bw.Commit(); e != nil {
126
+ err = e
127
+ }
128
+ }
129
+ return err
130
+ }
131
+
132
+ func (w *Writer) close() (err error) {
127
133
  if w.fe != nil {
128
134
  if e := w.fe.Close(); e != nil {
129
135
  err = e
@@ -139,11 +145,6 @@ func (w *Writer) Commit() error {
139
145
  err = e
140
146
  }
141
147
  }
142
- if w.bw != nil {
143
- if e := w.bw.Close(); e != nil {
144
- err = e
145
- }
146
- }
147
148
  return err
148
149
  }
149
150
 
@@ -21,10 +21,9 @@ var _ = Describe("Writer", func() {
21
21
  })
22
22
 
23
23
  It("should write plain", func() {
24
- w, err := feedx.NewWriter(context.Background(), plain, &feedx.WriterOptions{
24
+ w := feedx.NewWriter(context.Background(), plain, &feedx.WriterOptions{
25
25
  LastMod: time.Unix(1515151515, 123456789),
26
26
  })
27
- Expect(err).NotTo(HaveOccurred())
28
27
  defer w.Discard()
29
28
 
30
29
  Expect(w.Write(bytes.Repeat([]byte{'x'}, 10000))).To(Equal(10000))
@@ -37,10 +36,9 @@ var _ = Describe("Writer", func() {
37
36
  })
38
37
 
39
38
  It("should write compressed", func() {
40
- w, err := feedx.NewWriter(context.Background(), compressed, &feedx.WriterOptions{
39
+ w := feedx.NewWriter(context.Background(), compressed, &feedx.WriterOptions{
41
40
  LastMod: time.Unix(1515151515, 123456789),
42
41
  })
43
- Expect(err).NotTo(HaveOccurred())
44
42
  defer w.Discard()
45
43
 
46
44
  Expect(w.Write(bytes.Repeat([]byte{'x'}, 10000))).To(Equal(10000))
@@ -58,7 +56,7 @@ var _ = Describe("Writer", func() {
58
56
 
59
57
  info, err := plain.Head(ctx)
60
58
  Expect(err).NotTo(HaveOccurred())
61
- Expect(info.Size).To(BeNumerically("~", 470, 10))
59
+ Expect(info.Size).To(BeNumerically("~", 370, 10))
62
60
  Expect(info.Metadata).To(Equal(bfs.Metadata{"X-Feedx-Last-Modified": "1515151515123"}))
63
61
 
64
62
  info, err = compressed.Head(ctx)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feedx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Black Square Media Ltd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-08 00:00:00.000000000 Z
11
+ date: 2020-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bfs
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: red-parquet
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +150,8 @@ files:
136
150
  - format_test.go
137
151
  - go.mod
138
152
  - go.sum
153
+ - internal/testdata/testdata.pb.go
154
+ - internal/testdata/testdata.proto
139
155
  - lib/feedx.rb
140
156
  - lib/feedx/cache.rb
141
157
  - lib/feedx/cache/abstract.rb
@@ -149,6 +165,7 @@ files:
149
165
  - lib/feedx/format.rb
150
166
  - lib/feedx/format/abstract.rb
151
167
  - lib/feedx/format/json.rb
168
+ - lib/feedx/format/parquet.rb
152
169
  - lib/feedx/format/protobuf.rb
153
170
  - lib/feedx/producer.rb
154
171
  - lib/feedx/pusher.rb
@@ -165,6 +182,7 @@ files:
165
182
  - spec/feedx/consumer_spec.rb
166
183
  - spec/feedx/format/abstract_spec.rb
167
184
  - spec/feedx/format/json_spec.rb
185
+ - spec/feedx/format/parquet_spec.rb
168
186
  - spec/feedx/format/protobuf_spec.rb
169
187
  - spec/feedx/format_spec.rb
170
188
  - spec/feedx/producer_spec.rb
@@ -191,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
191
209
  - !ruby/object:Gem::Version
192
210
  version: '0'
193
211
  requirements: []
194
- rubygems_version: 3.0.6
212
+ rubygems_version: 3.1.4
195
213
  signing_key:
196
214
  specification_version: 4
197
215
  summary: Exchange data between components via feeds
@@ -204,6 +222,7 @@ test_files:
204
222
  - spec/feedx/consumer_spec.rb
205
223
  - spec/feedx/format/abstract_spec.rb
206
224
  - spec/feedx/format/json_spec.rb
225
+ - spec/feedx/format/parquet_spec.rb
207
226
  - spec/feedx/format/protobuf_spec.rb
208
227
  - spec/feedx/format_spec.rb
209
228
  - spec/feedx/producer_spec.rb