simple-feed 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://img.shields.io/gem/v/simple-feed.svg)](https://rubygems.org/gems/simple-feed)
|
4
5
|
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/kigster/simple-feed/master/LICENSE.txt)
|
6
|
+
|
5
7
|
[![Build Status](https://travis-ci.org/kigster/simple-feed.svg?branch=master)](https://travis-ci.org/kigster/simple-feed)
|
6
8
|
[![Code Climate](https://codeclimate.com/repos/58339a5b3d9faa74ac006b36/badges/8b899f6df4fc1ed93759/gpa.svg)](https://codeclimate.com/repos/58339a5b3d9faa74ac006b36/feed)
|
7
9
|
[![Test Coverage](https://codeclimate.com/repos/58339a5b3d9faa74ac006b36/badges/8b899f6df4fc1ed93759/coverage.svg)](https://codeclimate.com/repos/58339a5b3d9faa74ac006b36/coverage)
|
8
10
|
[![Issue Count](https://codeclimate.com/repos/58339a5b3d9faa74ac006b36/badges/8b899f6df4fc1ed93759/issue_count.svg)](https://codeclimate.com/repos/58339a5b3d9faa74ac006b36/feed)
|
9
11
|
[![Inline docs](http://inch-ci.org/github/kigster/simple-feed.svg?branch=master)](http://inch-ci.org/github/kigster/simple-feed)
|
12
|
+
[![Talk on Gitter](https://img.shields.io/gitter/room/gitterHQ/gitter.svg)](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
|
+
[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](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
|