Skip to content

Commit

Permalink
Add functionality to support different timeslice durations for differ…
Browse files Browse the repository at this point in the history
…ent wikis
  • Loading branch information
gabina committed Dec 27, 2024
1 parent 646e03f commit 1731322
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 39 deletions.
4 changes: 2 additions & 2 deletions app/controllers/courses_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,8 @@ def update_course_format
end

def update_timeslice_duration
# Set the timeslice_duration to the default value
@course.flags[:timeslice_duration] = TimesliceManager::TIMESLICE_DURATION
# Set the default timeslice_duration to the default value
@course.flags[:timeslice_duration] = { default: TimesliceManager::TIMESLICE_DURATION }
@course.save
end

Expand Down
4 changes: 0 additions & 4 deletions app/models/course.rb
Original file line number Diff line number Diff line change
Expand Up @@ -519,10 +519,6 @@ def no_sandboxes?
flags[:no_sandboxes].present?
end

def timeslice_duration
(flags[:timeslice_duration] || TimesliceManager::TIMESLICE_DURATION).seconds
end

#################
# Cache methods #
#################
Expand Down
5 changes: 3 additions & 2 deletions app/services/update_course_wiki_timeslices.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ def fetch_data_and_process_timeslices(wiki, first_start, latest_start)
current_start = first_start
while current_start <= latest_start
start_date = [current_start, @course.start].max
end_date = [current_start + @course.timeslice_duration - 1.second, @course.end].min
end_date = [current_start + @timeslice_manager.timeslice_duration(wiki) - 1.second,
@course.end].min
fetch_data(wiki, start_date, end_date)
process_timeslices(wiki)
current_start += @course.timeslice_duration
current_start += @timeslice_manager.timeslice_duration(wiki)
end
@debugger.log_update_progress :fetch_and_process_timeslices_finish
end
Expand Down
12 changes: 6 additions & 6 deletions app/services/update_timeslices_course_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ def fetch_users_revisions_for_wiki(wiki, user_ids, first_start, latest_start)
users = User.find(user_ids)

manager = RevisionDataManager.new(wiki, @course)
current_end = latest_start + @course.timeslice_duration
current_end = latest_start + @timeslice_manager.timeslice_duration(wiki)
# Fetch the revisions for users for the complete period
revisions = manager.fetch_revision_data_for_users(users,
current_start.strftime('%Y%m%d%H%M%S'),
current_end.strftime('%Y%m%d%H%M%S'))
wikis_and_starts = revisions_to_wiki_and_start_dates(revisions,
wiki.id,
wiki,
first_start,
latest_start)

Expand Down Expand Up @@ -87,19 +87,19 @@ def get_article_course_timeslices_for_users(user_ids)
timeslices.flatten
end

def revisions_to_wiki_and_start_dates(revisions, wiki_id, first_start, latest_start)
def revisions_to_wiki_and_start_dates(revisions, wiki, first_start, latest_start)
tuples = []
current_start = first_start
while current_start <= latest_start
current_end = current_start + @course.timeslice_duration
current_end = current_start + @timeslice_manager.timeslice_duration(wiki)
revisions_per_timeslice = revisions.select do |r|
current_start <= r.date && r.date < current_end
end
unless revisions_per_timeslice.empty?
tuples += [[wiki_id,
tuples += [[wiki.id,
current_start.strftime('%Y%m%d%H%M%S')]]
end
current_start += @course.timeslice_duration
current_start += @timeslice_manager.timeslice_duration(wiki)
end
tuples
end
Expand Down
5 changes: 3 additions & 2 deletions app/services/update_timeslices_course_wiki.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,17 @@ def remove_courses_wikis(wiki_ids)
end

def add_courses_wikis(wiki_ids)
wikis = Wiki.where(wiki_id: wiki_ids)
# Create course wiki timeslice records for new wikis
@timeslice_manager.create_timeslices_for_new_course_wiki_records wiki_ids
@timeslice_manager.create_timeslices_for_new_course_wiki_records(wikis)
end

def update_timeslices_durations
@course.wikis.each do |wiki|
start = @timeslice_manager.get_ingestion_start_time_for_wiki wiki
timeslice = @course.course_wiki_timeslices.where(wiki:, start:).first
effective_timeslice_duration = timeslice.end - timeslice.start
real_timeslice_duration = @course.timeslice_duration
real_timeslice_duration = @timeslice_manager.timeslice_duration(wiki)
# Continue if timeslice duration didn't change for the wiki
next unless effective_timeslice_duration != real_timeslice_duration
@timeslice_manager.delete_course_wiki_timeslices_after_date([wiki], start - 1.second)
Expand Down
48 changes: 27 additions & 21 deletions lib/timeslice_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ def initialize(course)
@course = course
end

def timeslice_duration(wiki)
begin
flag = @course.flags[:timeslice_duration]
flag[wiki.domain.to_sym] || flag[:default]
rescue StandardError
TIMESLICE_DURATION
end.seconds
end

# Deletes course user wiki timeslices records for removed course users
# Takes a collection of user ids
def delete_course_user_timeslices_for_deleted_course_users(user_ids)
Expand Down Expand Up @@ -96,24 +105,23 @@ def delete_course_user_wiki_timeslices_after_end_date
# Creates course user timeslices records for new course wiki
# Takes a collection of Wikis
def create_timeslices_for_new_course_wiki_records(wikis)
courses_wikis = @course.courses_wikis.where(wiki: wikis)
create_empty_course_wiki_timeslices(start_dates, courses_wikis)
wikis.each do |wiki|
create_empty_course_wiki_timeslices(start_dates(wiki), wiki)
end
end

# Creates course wiki timeslices records for missing timeslices due to a change in the start date
# Creates course user wiki timeslices records for missing timeslices
def create_wiki_timeslices_for_new_course_start_date(wiki)
courses_wikis = @course.courses_wikis.where(wiki:)
# Notice that start_dates_backward should use the timeslice duration for the specific wiki
create_empty_course_wiki_timeslices(start_dates_backward, courses_wikis, needs_update: true)
create_empty_course_wiki_timeslices(start_dates_backward(wiki), wiki,
needs_update: true)
end

# Creates course wiki timeslices records for missing timeslices due to a change in the end date
# Creates course user wiki timeslices records for missing timeslices
def create_wiki_timeslices_up_to_new_course_end_date(wiki)
courses_wikis = @course.courses_wikis.where(wiki:)
# Notice that start_dates_from_old_end should use the timeslice duration for the specific wiki
create_empty_course_wiki_timeslices(start_dates_from_old_end, courses_wikis, needs_update: true)
create_empty_course_wiki_timeslices(start_dates_from_old_end(wiki), wiki,
needs_update: true)
end

# Returns a datetime with the date to start getting revisions.
Expand Down Expand Up @@ -202,13 +210,11 @@ def update_course_wiki_timeslices_that_need_update(wikis_and_starts)
private

# Creates empty course wiki timeslices
def create_empty_course_wiki_timeslices(starts, courses_wikis, needs_update: false)
def create_empty_course_wiki_timeslices(starts, wiki, needs_update: false)
new_records = starts.map do |start|
courses_wikis.map do |c_w|
{ course_id: @course.id, wiki_id: c_w.wiki_id, start:,
end: start + @course.timeslice_duration, needs_update: }
end
end.flatten
{ course_id: @course.id, wiki_id: wiki.id, start:,
end: start + timeslice_duration(wiki), needs_update: }
end

return if new_records.empty?
# Do this in batches to avoid running the MySQL server out of memory
Expand Down Expand Up @@ -263,41 +269,41 @@ def delete_existing_article_course_timeslices(wiki_ids)

# Returns start dates from the course start up to course end, for timeslices with
# TIMESLICE_DURATION.
def start_dates
def start_dates(wiki)
start_dates = []
current_start = @course.start
while current_start <= @course.end
start_dates << current_start
current_start += @course.timeslice_duration
current_start += timeslice_duration(wiki)
end

start_dates
end

# Returns start dates from the old course start up to the new (previous) course start,
# for timeslices with TIMESLICE_DURATION.
def start_dates_backward
def start_dates_backward(wiki)
start_dates = []
# There is no guarantee that all wikis are in the same state.
last_start = CourseWikiTimeslice.max_min_course_start(@course)
current_start = last_start - @course.timeslice_duration
current_start = last_start - timeslice_duration(wiki)
while current_start >= @course.start
start_dates << current_start
current_start -= @course.timeslice_duration
current_start -= timeslice_duration(wiki)
end

start_dates
end

# Returns start dates from the old course end up to the new (later) course end,
# for timeslices with TIMESLICE_DURATION.
def start_dates_from_old_end
def start_dates_from_old_end(wiki)
start_dates = []
# There is no guarantee that all wikis are in the same state.
current_start = CourseWikiTimeslice.min_max_course_end(@course)
while current_start <= @course.end
start_dates << current_start
current_start += @course.timeslice_duration
current_start += timeslice_duration(wiki)
end

start_dates
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/timeslice_manager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
describe '#create_wiki_timeslices_for_new_course_start_date' do
before do
create(:courses_wikis, wiki: wikibooks, course:)
timeslice_manager.create_timeslices_for_new_course_wiki_records(wikibooks)
timeslice_manager.create_timeslices_for_new_course_wiki_records([wikibooks])
course.update(start: '2023-12-20')
course.reload
end
Expand All @@ -82,7 +82,7 @@
describe '#create_wiki_timeslices_up_to_new_course_end_date' do
before do
create(:courses_wikis, wiki: wikibooks, course:)
timeslice_manager.create_timeslices_for_new_course_wiki_records(wikibooks)
timeslice_manager.create_timeslices_for_new_course_wiki_records([wikibooks])
course.update(end: '2024-04-30')
course.reload
end
Expand Down

0 comments on commit 1731322

Please sign in to comment.