Skip to content
Browse files
Make frontend fields stateless to resolve repeating content issues.
This eliminates the concept of a store for timeline data, which was just
going to the client anyway when cookie store was enabled. Instead, the
entire timeline worth of content will be sent to the client. This
timeline is not reliant on getting a cookie back which could have been
overwritten in the client by a simultaneous request.

If a reliable store for this data is found, the store concept could be
reinstated. However the only reason for this would seem to be if the
client could not store the whole timeline, which seems unlikely.

See #1329.
  • Loading branch information
mikldt committed Mar 20, 2016
1 parent f5cd0a1 commit 1416e09ee80f01c1103bfb13e2ad47a08c9b2507
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 40 deletions.
@@ -22,19 +22,14 @@ def index

shuffle_config = FieldConfig.get(@screen, @field, 'shuffler') || DEFAULT_SHUFFLE
shuffler_klass = FrontendContentOrder.load_shuffler(shuffle_config)
session_key = "frontend_#{}_#{}_#{}_#{shuffler_klass}".to_sym
shuffler = nil
count = 1

count = 20 if FieldConfig.get(@screen, @field, 'marquee') == '1'

run_callbacks :index do # Run plugin hooks
shuffler =, @field, @subscriptions, session[session_key])
@content = shuffler.next_contents(count)
shuffler =, @field, @subscriptions)
@content = shuffler.next_contents()

auth! object: @content
session[session_key] = shuffler.save_session()

@content.each do |c|
@@ -7,40 +7,19 @@ class BaseShuffle
# @param [Screen] screen Screen showing the content.
# @param [Field] field Field showing the content.
# @param [Array<Subscription>] subscriptions All the subscriptions to use.
# @param [Array<Integer>] store Array to store a timeline if needed.
# @param [Hash] options Any additional options.
def initialize(screen, field, subscriptions, store=[], options={})
def initialize(screen, field, subscriptions, options={})
@screen = screen
@field = field
@subscriptions = subscriptions
@store = store
@options = options

@store = [] if @store.nil?

# Return the next set content to be shown.
# @param [Integer] count Number of content needed, defaults to 1.
# @return [Array<Content>] Next content that should be rendered.
def next_contents(count=1)
if @store.length < count
content = content()
@store += content.collect{|c|}
return [] if @store.empty?

content_ids = @store.shift(count)
Content.where(id: content_ids).to_a.compact

# Return a timeline to be saved.
# Since we can't directly access the session, the controller
# will pull here for what should be saved.
# @return [Array<Integer>] Array of content ids in the timeline.
def save_session()
def next_contents()

@@ -6,15 +6,8 @@
# then jumbled up and served from a timeline.
class WeightedShuffle < BaseShuffle

def next_contents(count=1)
if @store.length < count
content = weighted_content()
@store += content.collect{|c|}
return [] if @store.empty?

content_ids = @store.shift(count)
Content.where(id: content_ids).to_a.compact
def next_contents()


0 comments on commit 1416e09

Please sign in to comment.