simple-feed 2.0.1 → 2.0.2
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 +4 -4
- data/.travis.yml +2 -2
- data/README.md +45 -50
- data/Rakefile +14 -0
- data/examples/shared/provider_example.rb +2 -2
- data/lib/simplefeed.rb +2 -0
- data/lib/simplefeed/providers/base/provider.rb +0 -6
- data/lib/simplefeed/providers/redis/driver.rb +1 -6
- data/lib/simplefeed/providers/redis/provider.rb +0 -2
- data/lib/simplefeed/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0041dae8cf2aeff75f069680843b654093dad50
|
4
|
+
data.tar.gz: 6c21de78f66d8e964eecd08296f415061f288423
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a3377a50d75428dcc155bbb3d156fd6b8e394c845c690ec23d5a2b6e083a39feded268a40a80e16e5fe9cb33ad6f68f872a51690a0c4c3f7ada8587aad3ec54
|
7
|
+
data.tar.gz: 5c436ae8b4c7cac404f40aef9c7cf614c8dd8788a998d567139bd2cca0fc10c1a815943bc80374f10db8ef8375f5f6db3ee74af6c89253570b5e9b4ed78b5baf
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,69 +1,56 @@
|
|
1
1
|
# SimpleFeed — Scalable, easy to use activity feed implementation.
|
2
2
|
|
3
|
-
|
3
|
+
|
4
|
+
[](https://rubygems.org/gems/simple-feed)
|
4
5
|
[](https://github.com/kigster/simple-feed/master/LICENSE.txt)
|
6
|
+
|
5
7
|
[](https://travis-ci.org/kigster/simple-feed)
|
6
8
|
[](https://codeclimate.com/repos/58339a5b3d9faa74ac006b36/feed)
|
7
9
|
[](https://codeclimate.com/repos/58339a5b3d9faa74ac006b36/coverage)
|
8
10
|
[](https://codeclimate.com/repos/58339a5b3d9faa74ac006b36/feed)
|
9
11
|
[](http://inch-ci.org/github/kigster/simple-feed)
|
12
|
+
[](https://gitter.im/kigster/simple-feed)
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
__Important Notes and Acknowledgements:__
|
14
|
+
---
|
14
15
|
|
15
|
-
|
16
|
-
* __SimpleFeed requires ruby 2.3 or later.__
|
17
|
-
* SimpleFeed is currently live in production.
|
18
|
-
* We'd like to thank __[Simbi, Inc — Symbiotic Economy](http://simbi.com)__ for their sponsorship of the development of this open source library.
|
16
|
+
**February 20th, 2017**: Please read the blog post [Feeding Frenzy with SimpleFeed](http://kig.re/2017/02/19/feeding-frenzy-with-simple-feed-activity-feed-ruby-gem.html) launching this library. Please leave comments or questions in the discussion thread at the bottom of that post. Thanks!
|
19
17
|
|
20
|
-
|
18
|
+
---
|
21
19
|
|
22
|
-
|
23
|
-
>
|
24
|
-
> * personalized for a given user or a group, or global
|
25
|
-
> * aggregated across several actors for a similar event type, eg. "John, Mary, etc.. followed George"
|
26
|
-
> * filtered by a certain characteristic, such as:
|
27
|
-
> * the actor producing an event — i.e. people you follow on a social network, or "yourself" for your own activity
|
28
|
-
> * the type of an event (i.e. posts, likes, comments, stories, etc)
|
29
|
-
> * the target of an event (commonly a user, but can also be a thing you are interested in, e.g. a github repo you are watching)
|
20
|
+
If you like to see this project grow, your donation of any amount is much appreciated.
|
30
21
|
|
31
|
-
|
22
|
+
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FSFYYNEQ8RKWU)
|
32
23
|
|
33
|
-
|
24
|
+
---
|
34
25
|
|
35
|
-
|
26
|
+
This is a fast, pure-ruby implementation of an activity feed concept commonly used in social networking applications. The implementation is optimized for **read-time performance** and high concurrency (lots of users), and can be extended with custom backend providers. Two providers come bundled: the production-ready Redis provider, and a naive Ruby Hash-based provider.
|
36
27
|
|
37
|
-
|
28
|
+
__Important Notes and Acknowledgements:__
|
38
29
|
|
39
|
-
|
30
|
+
* SimpleFeed *does not depend on Ruby on Rails* and is a __pure-ruby__ implementation
|
31
|
+
* SimpleFeed requires ruby 2.3 or later
|
32
|
+
* SimpleFeed is currently live in production
|
33
|
+
* SimpleFeed is open source thanks to the generosity of __[Simbi, Inc](http://simbi.com)__.
|
40
34
|
|
41
|
-
|
42
|
-
* OR optimizing the various ranking algorithms by computing the feed at read time, with complex forms of caching addressing the performance requirements.
|
43
|
-
|
44
|
-
The first type of feed is much simpler to implement on a large scale (up to a point), and it scales well if the data is stored in a light-weight in-memory storage such as Redis. This is exactly the approach this library takes.
|
35
|
+
## Background, Examples, Serialization, etc
|
45
36
|
|
46
|
-
|
37
|
+
Please read the additional documentation, including the examples, on the [project's Github Wiki](https://github.com/kigster/simple-feed/wiki).
|
47
38
|
|
48
|
-
|
49
|
-
- ["Feeding Frenzy: Selectively Materializing Users’ Event Feeds"](http://jeffterrace.com/docs/feeding-frenzy-sigmod10-web.pdf) (Yahoo! Research paper).
|
39
|
+
## Usage
|
50
40
|
|
51
|
-
|
41
|
+
A key concept to understanding SimpleFeed gem, is that of a _provider_, which is effectively a persistence implementation for the events belonging to each user.
|
52
42
|
|
53
|
-
|
43
|
+
Two providers are supplied with this gem:
|
54
44
|
|
55
|
-
*
|
56
|
-
* To make it easy to implement and plug in a new type of provider, eg. using *Couchbase* or *MongoDB*
|
57
|
-
* To provide a scalable default provider implementation using Redis, which can support millions of users via sharding
|
58
|
-
* To support multiple simple feeds within the same application, but used for different purposes, eg. simple feed of my followers, versus simple feed of my own actions.
|
45
|
+
* The production-ready `:redis` provider, which uses the [sorted set Redis data type](https://redislabs.com/ebook/redis-in-action/part-2-core-concepts-2/chapter-3-commands-in-redis/3-5-sorted-sets) to store and fetch the events, scored by time (but not necessarily).
|
59
46
|
|
60
|
-
|
47
|
+
* The naïve `:hash` provider based on the ruby `Hash` class, that can be useful in unit tests, or in simple simulations.
|
61
48
|
|
62
|
-
|
49
|
+
You initialize a provider by using the `SimpleFeed.provider([Symbol])` method.
|
63
50
|
|
64
51
|
### Configuration
|
65
52
|
|
66
|
-
Below we configure a feed called `:newsfeed`, which
|
53
|
+
Below we configure a feed called `:newsfeed`, which in this example will be populated with the various events coming from the followers.
|
67
54
|
|
68
55
|
```ruby
|
69
56
|
require 'simplefeed'
|
@@ -110,7 +97,7 @@ application, not just the one that published the event (which is the
|
|
110
97
|
case for the "toy" `Hash::Provider`.
|
111
98
|
|
112
99
|
```ruby
|
113
|
-
activity.paginate(page: 1)
|
100
|
+
activity.paginate(page: 1, reset_last_read: true)
|
114
101
|
# => [ <SimpleFeed::Event#0x2134afa value='hello' at='2016-11-20 23:32:56 -0800'> ]
|
115
102
|
```
|
116
103
|
|
@@ -158,8 +145,8 @@ activity.unread_count # => 0
|
|
158
145
|
activity.store(value: 'hello') # => true
|
159
146
|
activity.store(value: 'goodbye', at: Time.now - 20) # => true
|
160
147
|
activity.unread_count # => 2
|
161
|
-
# Now we can paginate the events,
|
162
|
-
activity.paginate(page: 1)
|
148
|
+
# Now we can paginate the events, while resetting this user's last-read timestamp:
|
149
|
+
activity.paginate(page: 1, reset_last_read: true)
|
163
150
|
# [
|
164
151
|
# [0] #<SimpleFeed::Event: value=good bye, at=1480475294.0579991>,
|
165
152
|
# [1] #<SimpleFeed::Event: value=hello, at=1480475294.057138>
|
@@ -179,7 +166,7 @@ end
|
|
179
166
|
activity.total_count # => 0
|
180
167
|
```
|
181
168
|
|
182
|
-
You can fetch all items (optionally filtered by time) in the feed using `#fetch`,
|
169
|
+
You can fetch all items (optionally filtered by time) in the feed using `#fetch`,
|
183
170
|
`#paginate` and reset the `last_read` timestamp by passing the `reset_last_read: true` as a parameter.
|
184
171
|
|
185
172
|
<a name="batch-api"/>
|
@@ -296,7 +283,10 @@ end
|
|
296
283
|
# => [Response] { user_id => [Boolean], ... } true if user activity was found and deleted, false otherwise
|
297
284
|
|
298
285
|
# Return a paginated list of all items, optionally with the total count of items
|
299
|
-
@multi.paginate(page
|
286
|
+
@multi.paginate(page: 1,
|
287
|
+
per_page: @multi.feed.per_page,
|
288
|
+
with_total: false,
|
289
|
+
reset_last_read: false)
|
300
290
|
# => [Response] { user_id => [Array]<Event>, ... }
|
301
291
|
# Options:
|
302
292
|
# reset_last_read: false — reset last read to Time.now (true), or the provided timestamp
|
@@ -325,21 +315,26 @@ end
|
|
325
315
|
|
326
316
|
```
|
327
317
|
|
328
|
-
## Providers
|
318
|
+
## Providers in Depth
|
329
319
|
|
330
|
-
|
320
|
+
As we've discussed above, a provider is an underlying persistence mechanism implementation.
|
331
321
|
|
332
322
|
It is the intention of this gem that:
|
333
323
|
|
334
|
-
* it should be easy to
|
335
|
-
* it should be easy to
|
324
|
+
* it should be easy to write new providers
|
325
|
+
* it should be easy to swap out providers
|
336
326
|
|
337
|
-
|
338
|
-
above (the `Feed` version, that receives `user_ids:` as arguments).
|
327
|
+
To create a new provider please use `SimpleFeed::Providers::Hash::Provider` class as a starting point.
|
339
328
|
|
340
329
|
Two providers are available with this gem:
|
341
330
|
|
342
|
-
|
331
|
+
### `SimpleFeed::Providers::Redis::Provider`
|
332
|
+
|
333
|
+
Redis Provider is a production-ready persistence adapter that uses the [sorted set Redis data type](https://redislabs.com/ebook/redis-in-action/part-2-core-concepts-2/chapter-3-commands-in-redis/3-5-sorted-sets).
|
334
|
+
|
335
|
+
This provider is optimized for large writes and can use either a single Redis instance for all users of your application, or any number of Redis [shards](https://en.wikipedia.org/wiki/Shard_(database_architecture)) by using a [_Twemproxy_](https://github.com/twitter/twemproxy) in front of the Redis shards.
|
336
|
+
|
337
|
+
While future
|
343
338
|
|
344
339
|
* `SimpleFeed::Providers::HashProvider` is a pure Hash-like implementation of a provider that can be useful in unit tests of a host application. This provider could be used to write and read events within a single ruby process, can be serialized to and from a YAML file, and is therefore intended primarily for Feed emulations in automated tests.
|
345
340
|
|
data/Rakefile
CHANGED
@@ -4,6 +4,20 @@ require 'rspec/core/rake_task'
|
|
4
4
|
require 'yard'
|
5
5
|
|
6
6
|
|
7
|
+
def shell(*args)
|
8
|
+
puts "running: #{args.join(' ')}"
|
9
|
+
system(args.join(' '))
|
10
|
+
end
|
11
|
+
|
12
|
+
task :permissions do
|
13
|
+
shell('rm -rf pkg/')
|
14
|
+
shell("chmod -v o+r,g+r * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*")
|
15
|
+
shell("find . -type d -exec chmod o+x,g+x {} \\;")
|
16
|
+
end
|
17
|
+
|
18
|
+
task :build => :permissions
|
19
|
+
|
20
|
+
|
7
21
|
YARD::Rake::YardocTask.new(:doc) do |t|
|
8
22
|
t.files = %w(lib/**/*.rb exe/*.rb - README.md LICENSE.txt)
|
9
23
|
t.options.unshift('--title', '"SimpleFeed — Fast and Scalable "write-time" Simple Feed for Social Networks, with a Redis-based default backend implementation."')
|
@@ -40,8 +40,8 @@ with_activity(@activity) do
|
|
40
40
|
|
41
41
|
header 'paginate(page: 1, per_page: 2)'
|
42
42
|
paginate(page: 1, per_page: 2) { |r| puts r[@uid].map(&:to_color_s) }
|
43
|
-
header 'paginate(page: 2, per_page: 2)'
|
44
|
-
paginate(page: 2, per_page: 2) { |r| puts r[@uid].map(&:to_color_s) }
|
43
|
+
header 'paginate(page: 2, per_page: 2, reset_last_read: true)'
|
44
|
+
paginate(page: 2, per_page: 2, reset_last_read: true) { |r| puts r[@uid].map(&:to_color_s) }
|
45
45
|
|
46
46
|
hr
|
47
47
|
|
data/lib/simplefeed.rb
CHANGED
@@ -20,12 +20,6 @@ module SimpleFeed
|
|
20
20
|
SimpleFeed::Providers.register(class_to_registry(klass), klass)
|
21
21
|
end
|
22
22
|
|
23
|
-
# SimpleFeed::Providers::REQUIRED_METHODS.each do |m|
|
24
|
-
# define_method(m) do |*|
|
25
|
-
# raise ::SimpleFeed::Providers::NotImplementedError.new(self, m)
|
26
|
-
# end
|
27
|
-
# end
|
28
|
-
|
29
23
|
protected
|
30
24
|
|
31
25
|
def reset_last_read_value(user_ids:, at: nil)
|
@@ -121,12 +121,7 @@ SimpleFeed::Redis::Driver.new(redis: { host: 'localhost', port: 6379, db: 1, tim
|
|
121
121
|
send_proc = redis_method if redis_method.respond_to?(:call)
|
122
122
|
send_proc ||= ->(redis) { redis.send(redis_method, *args, &block) }
|
123
123
|
|
124
|
-
|
125
|
-
opts.delete :pipelined
|
126
|
-
with_pipelined { |redis| send_proc.call(redis) }
|
127
|
-
else
|
128
|
-
with_redis { |redis| send_proc.call(redis) }
|
129
|
-
end
|
124
|
+
with_redis { |redis| send_proc.call(redis) }
|
130
125
|
end
|
131
126
|
|
132
127
|
class MockRedis
|
data/lib/simplefeed/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-feed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Gredeskoul
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: base62-rb
|
@@ -314,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
314
314
|
version: '0'
|
315
315
|
requirements: []
|
316
316
|
rubyforge_project:
|
317
|
-
rubygems_version: 2.6.
|
317
|
+
rubygems_version: 2.6.13
|
318
318
|
signing_key:
|
319
319
|
specification_version: 4
|
320
320
|
summary: Create multiple types of social networking activity feeds with simple-feed
|