CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
m (Including current implementation)
(Including new implementation)
Line 32: Line 32:
::- The teams are not permitted to drop the assigned topics anymore.  
::- The teams are not permitted to drop the assigned topics anymore.  


::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (sidekick), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.




== '''Corrections made in the New Project''' ==
=====Drawbacks and Solutions=====


* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.
::Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same.


1. The instructor can specify a Drop Topic deadline date now. After a drop topic deadline passes, the "X"(signup option) in the Sign-Up sheet disables so that the student cannot drop the topic and the wait-list for that topic is cleared, which will resolve the issue of the topic being assigned to a wait-listed team very close to the submission deadline.
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.
<pre>
  # adds a new deadline if not present,
  # updates the date if already present
  def self.modify_drop_deadline(topic, drop_topic_date)
    # can create constants for all deadline type and use those when required
    deadline_type_id = DeadlineType.find_by_name("drop_topic").id
    topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil
    if topic_due_date.nil?
      # save the newly entered date
      TopicDueDate.create(
        due_at: drop_topic_date,
        parent_id: topic.id,
        deadline_type_id: deadline_type_id,
        type: DeadlineHelper::TOPIC_DEADLINE_TYPE)
    else
      # update the existing date if different
      if topic_due_date.due_at != drop_topic_date
        topic_due_date.update_attributes(
          due_at: drop_topic_date
        )
      end
    end
  end
</pre>
 
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.
::For executing the timed jobs, we are using Sidekiq, and creating jobs for every Topic. Referred to as delayed_jobs, we currently have some defined for tasks like dropping a team when the last member leaves, etc.
 
* '''Solution''': We have added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. Whenever there is any update on the Deadlines by the instructor, we fetch the existing job, if any, by the delayed_job_id, and modify the same as per the new Deadline.


2. Staggered deadline assignments now have different drop deadlines for different topics in that assignment.The above resolution also works for Staggered Deadlines Assignment
<pre>
  # This method either adds a new job to the queue or deletes
  # an existing job and replaces it with a new one
  def modify_delayed_job(topic, delayed_job_id, job_present)
    if job_present == false
      min_left = topic.due_at - Time.now
      delayed_job_id = add_job_to_queue(min_left, topic.id, "drop_topic", topic.due_at)
      delayed_job_id
    else
      remove_job_from_queue(delayed_job_id)
      min_left = topic.due_at - Time.now
      delayed_job_id = add_job_to_queue(min_left, topic.id, "drop_topic", topic.due_at)
      delayed_job_id
    end
  end
 
  def add_job_to_queue(min_left, topic_id, deadline_type, due_at)
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)
    return delayed_job_id
  end
 
  def remove_job_from_queue(job_id)
    queue = Sidekiq::ScheduledSet.new
    queue.each do |job|
      current_job_id = job.args.first
      job.delete if job_id == current_job_id
    end
  end
</pre>




Line 58: Line 117:
6. app/views/sign_up_sheet/_due_dates.html.erb
6. app/views/sign_up_sheet/_due_dates.html.erb


== '''Current Implementation''' ==
1. Clearing the waitlist after Drop Deadline passes is implemented in sign_up_sheet_controller.rb where it is checked if the current time is greater than the time mentioned in Drop deadline. If the deadline has been passed, the 'update_is_waitlisted' method of SignedUpTeam model is called to delete all the waitlisted teams for that topic.
2. Changes are made in Assignments View to add an additional column for Drop-Topic Deadline for Staggered Deadlines Assignment. The code snippets for corresponding changes in controllers and models are as below:
(i) app/controllers/sign_up_sheet_controller.rb
    if !topic_id1.nil? and !@drop_topic_deadline1.nil? and Time.now > @drop_topic_deadline1.due_at
    SignedUpTeam.update_is_waitlisted(topic_id1.topic_id,team_id) end
(ii) The 'update_is_waitlisted' method is implemented in app/models/signed_up_team.rb as follows:
    def self.update_is_waitlisted(topic_i)
    topic_id1 = SignedUpTeam.where(team_id: team_id).first
    if @assignment.staggered_deadline?
    @drop_topic_deadline1 = TopicDueDate.where(parent_id: topic_id1.topic_id, deadline_type_id: 6).first rescue nil end
    due_dates = params[:due_date]
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])
    review_rounds = assignment.num_review_rounds
    topics.each_with_index do |topic, index|
    for i in 1..review_rounds
        @topic_drop_topic_due_date = due_dates[topics[index].id.to_s + '_drop_topic_' + i.to_s + '_due_date']
        if assignment.due_dates.select {|due_date| due_date.deadline_type_id == 6 }.nil?
        @assignment_drop_topic_due_date = DateTime.parse(@assignment_drop_topic_due_dates[i - 1].due_at.to_s).strftime("%Y-%m-%d %H:%M")
    end
    end
(iii) app/helpers/sign_up_sheet_helper.rb
      if assignment_due_dates.length == 0
        assignment_due_dates = @assignment_submission_due_dates
      end
(iv) app/models/student_task.rb
    def self.get_due_date_data(assignment, timeline_list, participant)
    if assignment.staggered_deadline?
        team_id = participant.team.try(:id)
        topic_id1 = SignedUpTeam.where(team_id: team_id).first
        if !topic_id1.nil?
          topic_due_date = TopicDueDate.where(parent_id: topic_id1.topic_id, deadline_type_id: 6).first rescue nil
          timeline = {label: ('Drop Topic Deadline').humanize}
          timeline[:updated_at] = topic_due_date.due_at.strftime('%a, %d %b %Y %H:%M')
          timeline_list << timeline
        end
    end
    assignment.due_dates.each do |dd|
    timeline = {label: (dd.deadline_type.name + ' Deadline').humanize}
    unless dd.due_at.nil?
          timeline[:updated_at] = dd.due_at.strftime('%a, %d %b %Y %H:%M')
          timeline_list << timeline
    end
    end
    end
(v) app/views/assignments/edit.html.erb
    <% if @assignment_form.assignment.staggered_deadline == true %>
    <%= render partial: '/sign_up_sheet/add_signup_topics_staggered', locals: {review_rounds: @review_rounds, assignment_submission_due_dates:        @assignment_submission_due_dates, assignment_review_due_dates: @assignment_review_due_dates, assignment_drop_topic_due_dates: @assignment_drop_topic_due_dates} %>
    <% else %>
    <%= render '/sign_up_sheet/add_signup_topics' %>
    <% end %>
(vi) app/views/sign_up_sheet/_add_signup_topics_staggered.html.erb
    <%= form_tag :controller => 'sign_up_sheet', :action => 'save_topic_deadlines', :assignment_id => @assignment.id do %>
    <br/><%= render :partial => '/sign_up_sheet/due_dates', :locals => {review_rounds: review_rounds, assignment_submission_due_dates:    assignment_submission_due_dates, assignment_review_due_dates: assignment_review_due_dates, assignment_drop_topic_due_dates: assignment_drop_topic_due_dates} %>
    <% end %>
(vii) app/views/sign_up_sheet/_due_dates.html.erb
      <tr>
      <th>Drop deadline</th>
      <%for i in 2..review_rounds%>
      <td><%= @assignment.sign_up_topics[i].topic_name %></td>
      <% for review_round in 1..review_rounds %>
      <% topic_id = @assignment.sign_up_topics[i].id %>
      <%if review_round == 1 %>
      <td><%= text_field :due_date, (topic_id.to_s + '_drop_topic_' + review_round.to_s + '_due_date').to_s, size: 20, value:    check_topic_due_date_value(assignment_drop_topic_due_dates, topic_id, 6, review_round) %></td>
      <td><%= text_field :due_date, (topic_id.to_s + '_submission_' + review_round.to_s + '_due_date').to_s, size: 20, value:  check_topic_due_date_value(assignment_submission_due_dates, topic_id, 1, review_round) %></td>
      <td><%= text_field :due_date, (topic_id.to_s + '_review_' + review_round.to_s + '_due_date').to_s, size: 20, value: check_topic_due_date_value(assignment_review_due_dates, topic_id, 2, review_round) %></td>
      <%else%>
      <td><%= text_field :due_date, (topic_id.to_s + '_submission_' + review_round.to_s + '_due_date').to_s, size: 20, value: check_topic_due_date_value(assignment_submission_due_dates, topic_id, 1, review_round) %></td>
      <td><%= text_field :due_date, (topic_id.to_s + '_review_' + review_round.to_s + '_due_date').to_s, size: 20, value: check_topic_due_date_value(assignment_review_due_dates, topic_id, 2, review_round) %></td> <%end%> <%end%>
      </tr>
      <%end%>


== '''Test Plan''' ==
== '''Test Plan''' ==


It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.
It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.


== '''References''' ==
== '''References''' ==

Revision as of 02:40, 29 October 2019

This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2018, CSC/ECE 517.


About Expertiza

Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.


Issues in the Current Project

  • There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.
  • There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for "Drop Topics Deadline". In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.


Current Implementation

Functionality
  • The instructor cannot add a Drop Topic Deadline for topics
The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, h/she can add in a date for Drop Topic Deadline as well.
  • The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline
Whenever the Drop Topic Deadline is crossed, we expect:
- The waitlist queue for the topic is cleared
- The teams are not permitted to drop the assigned topics anymore.
Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.


Drawbacks and Solutions
  • Problem 1: No provision for taking user input for Drop Topic Deadline and persisting it in the database.
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same.
  • Solution: The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.
  # adds a new deadline if not present,
  # updates the date if already present
  def self.modify_drop_deadline(topic, drop_topic_date)
    # can create constants for all deadline type and use those when required
    deadline_type_id = DeadlineType.find_by_name("drop_topic").id
    topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil
    if topic_due_date.nil?
      # save the newly entered date
      TopicDueDate.create(
        due_at: drop_topic_date,
        parent_id: topic.id,
        deadline_type_id: deadline_type_id,
        type: DeadlineHelper::TOPIC_DEADLINE_TYPE)
    else
      # update the existing date if different
      if topic_due_date.due_at != drop_topic_date
        topic_due_date.update_attributes(
          due_at: drop_topic_date
        )
      end
    end
  end
  • Problem 2: Waitlisted topics not getting dropped after the Drop Topic Deadline.
For executing the timed jobs, we are using Sidekiq, and creating jobs for every Topic. Referred to as delayed_jobs, we currently have some defined for tasks like dropping a team when the last member leaves, etc.
  • Solution: We have added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. Whenever there is any update on the Deadlines by the instructor, we fetch the existing job, if any, by the delayed_job_id, and modify the same as per the new Deadline.
  # This method either adds a new job to the queue or deletes
  # an existing job and replaces it with a new one
  def modify_delayed_job(topic, delayed_job_id, job_present)
    if job_present == false
      min_left = topic.due_at - Time.now
      delayed_job_id = add_job_to_queue(min_left, topic.id, "drop_topic", topic.due_at)
      delayed_job_id
    else
      remove_job_from_queue(delayed_job_id)
      min_left = topic.due_at - Time.now
      delayed_job_id = add_job_to_queue(min_left, topic.id, "drop_topic", topic.due_at)
      delayed_job_id
    end
  end

  def add_job_to_queue(min_left, topic_id, deadline_type, due_at)
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)
    return delayed_job_id
  end

  def remove_job_from_queue(job_id)
    queue = Sidekiq::ScheduledSet.new
    queue.each do |job|
      current_job_id = job.args.first
      job.delete if job_id == current_job_id
    end
  end


Files modified in Current Project

1. app/controllers/assignments_controller.rb

2. app/controllers/sign_up_sheet_controller.rb

3. app/models/student_task.rb

4. app/views/assignments/edit.html.erb

5. app/views/sign_up_sheet/_add_signup_topics_staggered.html.erb

6. app/views/sign_up_sheet/_due_dates.html.erb


Test Plan

It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.


References

1. Expertiza on GITHUB: https://github.com/expertiza/expertiza

2. GitHub Project Repository Fork: https://github.com/harshshah949494/expertiza

3. The live Expertiza website : https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1

4. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1

5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php?title=E1843_Issues_Related_To_Deadlines&action=edit&section=7 Link title