canvas_sync 0.23.4 → 0.24.0.beta1

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.
Files changed (206) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -4
  3. data/lib/canvas_sync/processors/provisioning_report_processor.rb +1 -0
  4. data/lib/canvas_sync/version.rb +1 -1
  5. data/lib/canvas_sync.rb +6 -4
  6. data/spec/canvas_sync/canvas_sync_spec.rb +11 -11
  7. data/spec/canvas_sync/live_events/process_event_job_spec.rb +1 -0
  8. data/spec/{dummy → internal}/app/models/application_record.rb +1 -0
  9. data/spec/{dummy → internal}/app/models/content_migration.rb +0 -0
  10. data/spec/{dummy → internal}/app/models/course.rb +0 -1
  11. data/spec/{dummy → internal}/app/models/course_nickname.rb +0 -0
  12. data/spec/{dummy → internal}/app/models/learning_outcome.rb +0 -0
  13. data/spec/{dummy → internal}/app/services/live_events/assignment_event.rb +0 -0
  14. data/spec/{dummy → internal}/app/services/live_events/course_event.rb +0 -0
  15. data/spec/{dummy → internal}/app/services/live_events/course_section_event.rb +0 -0
  16. data/spec/{dummy → internal}/app/services/live_events/enrollment_event.rb +0 -0
  17. data/spec/{dummy → internal}/app/services/live_events/grade_event.rb +0 -0
  18. data/spec/{dummy → internal}/app/services/live_events/module_event.rb +0 -0
  19. data/spec/{dummy → internal}/app/services/live_events/module_item_event.rb +0 -0
  20. data/spec/{dummy → internal}/app/services/live_events/submission_event.rb +0 -0
  21. data/spec/{dummy → internal}/app/services/live_events/syllabus_event.rb +0 -0
  22. data/spec/{dummy → internal}/app/services/live_events/user_event.rb +0 -0
  23. data/spec/internal/bin/rails +9 -0
  24. data/spec/internal/config/database.yml +5 -0
  25. data/spec/internal/config/routes.rb +5 -0
  26. data/spec/internal/config/storage.yml +3 -0
  27. data/spec/{dummy/db/migrate/20220926221926_create_users.rb → internal/db/migrate/20250912205136_create_users.rb} +0 -0
  28. data/spec/{dummy/db/migrate/20201016181346_create_pseudonyms.rb → internal/db/migrate/20250912205137_create_pseudonyms.rb} +0 -0
  29. data/spec/{dummy/db/migrate/20200415171620_create_groups.rb → internal/db/migrate/20250912205139_create_groups.rb} +0 -0
  30. data/spec/{dummy/db/migrate/20200416214248_create_group_memberships.rb → internal/db/migrate/20250912205140_create_group_memberships.rb} +0 -0
  31. data/spec/{dummy/db/migrate/20190702203622_create_accounts.rb → internal/db/migrate/20250912205141_create_accounts.rb} +0 -0
  32. data/spec/{dummy/db/migrate/20190702203623_create_terms.rb → internal/db/migrate/20250912205142_create_terms.rb} +0 -0
  33. data/spec/{dummy/db/migrate/20190702203625_create_sections.rb → internal/db/migrate/20250912205144_create_sections.rb} +0 -0
  34. data/spec/{dummy/db/migrate/20190702203626_create_assignments.rb → internal/db/migrate/20250912205145_create_assignments.rb} +0 -0
  35. data/spec/{dummy/db/migrate/20190702203627_create_submissions.rb → internal/db/migrate/20250912205146_create_submissions.rb} +0 -0
  36. data/spec/{dummy/db/migrate/20190927204545_create_roles.rb → internal/db/migrate/20250912205147_create_roles.rb} +2 -2
  37. data/spec/{dummy/db/migrate/20190927204546_create_admins.rb → internal/db/migrate/20250912205148_create_admins.rb} +0 -0
  38. data/spec/{dummy/db/migrate/20190702203630_create_assignment_groups.rb → internal/db/migrate/20250912205149_create_assignment_groups.rb} +0 -0
  39. data/spec/{dummy/db/migrate/20190702203631_create_context_modules.rb → internal/db/migrate/20250912205150_create_context_modules.rb} +0 -0
  40. data/spec/{dummy/db/migrate/20190702203632_create_context_module_items.rb → internal/db/migrate/20250912205151_create_context_module_items.rb} +0 -0
  41. data/spec/{dummy/db/migrate/20210907233329_create_user_observers.rb → internal/db/migrate/20250912205152_create_user_observers.rb} +0 -0
  42. data/spec/{dummy/db/migrate/20210907233330_create_grading_periods.rb → internal/db/migrate/20250912205153_create_grading_periods.rb} +0 -0
  43. data/spec/{dummy/db/migrate/20211001184920_create_grading_period_groups.rb → internal/db/migrate/20250912205154_create_grading_period_groups.rb} +0 -0
  44. data/spec/{dummy/db/migrate/20220308072643_create_content_migrations.rb → internal/db/migrate/20250912205155_create_content_migrations.rb} +0 -0
  45. data/spec/{dummy/db/migrate/20220712210559_create_learning_outcomes.rb → internal/db/migrate/20250912205156_create_learning_outcomes.rb} +0 -0
  46. data/spec/{dummy/db/migrate/20240523101010_create_learning_outcome_results.rb → internal/db/migrate/20250912205157_create_learning_outcome_results.rb} +0 -0
  47. data/spec/{dummy/db/migrate/20240510094100_create_rubric_associations.rb → internal/db/migrate/20250912205160_create_rubric_associations.rb} +0 -0
  48. data/spec/{dummy/db/migrate/20240510101100_create_rubric_assessments.rb → internal/db/migrate/20250912205161_create_rubric_assessments.rb} +0 -0
  49. data/spec/{dummy/db/migrate/20240828161300_create_course_progresses.rb → internal/db/migrate/20250912205162_create_course_progresses.rb} +0 -0
  50. data/spec/internal/db/schema.rb +6 -0
  51. data/spec/spec_helper.rb +8 -4
  52. metadata +182 -372
  53. data/lib/canvas_sync/job_batches/batch.rb +0 -595
  54. data/lib/canvas_sync/job_batches/callback.rb +0 -135
  55. data/lib/canvas_sync/job_batches/chain_builder.rb +0 -247
  56. data/lib/canvas_sync/job_batches/compat/active_job.rb +0 -108
  57. data/lib/canvas_sync/job_batches/compat/sidekiq/web/batches_assets/css/styles.less +0 -182
  58. data/lib/canvas_sync/job_batches/compat/sidekiq/web/batches_assets/js/batch_tree.js +0 -108
  59. data/lib/canvas_sync/job_batches/compat/sidekiq/web/batches_assets/js/util.js +0 -2
  60. data/lib/canvas_sync/job_batches/compat/sidekiq/web/helpers.rb +0 -41
  61. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_batch_tree.erb +0 -6
  62. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_batches_table.erb +0 -44
  63. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_common.erb +0 -13
  64. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_jobs_table.erb +0 -21
  65. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_pagination.erb +0 -26
  66. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/batch.erb +0 -81
  67. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/batches.erb +0 -23
  68. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/pool.erb +0 -137
  69. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/pools.erb +0 -47
  70. data/lib/canvas_sync/job_batches/compat/sidekiq/web.rb +0 -218
  71. data/lib/canvas_sync/job_batches/compat/sidekiq.rb +0 -149
  72. data/lib/canvas_sync/job_batches/compat.rb +0 -20
  73. data/lib/canvas_sync/job_batches/context_hash.rb +0 -157
  74. data/lib/canvas_sync/job_batches/hier_batch_ids.lua +0 -25
  75. data/lib/canvas_sync/job_batches/jobs/base_job.rb +0 -5
  76. data/lib/canvas_sync/job_batches/jobs/concurrent_batch_job.rb +0 -20
  77. data/lib/canvas_sync/job_batches/jobs/managed_batch_job.rb +0 -175
  78. data/lib/canvas_sync/job_batches/jobs/serial_batch_job.rb +0 -20
  79. data/lib/canvas_sync/job_batches/pool.rb +0 -254
  80. data/lib/canvas_sync/job_batches/pool_refill.lua +0 -47
  81. data/lib/canvas_sync/job_batches/redis_model.rb +0 -67
  82. data/lib/canvas_sync/job_batches/redis_script.rb +0 -161
  83. data/lib/canvas_sync/job_batches/schedule_callback.lua +0 -14
  84. data/lib/canvas_sync/job_batches/status.rb +0 -89
  85. data/lib/canvas_sync/job_uniqueness/compat/active_job.rb +0 -75
  86. data/lib/canvas_sync/job_uniqueness/compat/sidekiq.rb +0 -135
  87. data/lib/canvas_sync/job_uniqueness/compat.rb +0 -20
  88. data/lib/canvas_sync/job_uniqueness/configuration.rb +0 -25
  89. data/lib/canvas_sync/job_uniqueness/job_uniqueness.rb +0 -47
  90. data/lib/canvas_sync/job_uniqueness/lock_context.rb +0 -199
  91. data/lib/canvas_sync/job_uniqueness/locksmith.rb +0 -92
  92. data/lib/canvas_sync/job_uniqueness/on_conflict/base.rb +0 -32
  93. data/lib/canvas_sync/job_uniqueness/on_conflict/log.rb +0 -13
  94. data/lib/canvas_sync/job_uniqueness/on_conflict/null_strategy.rb +0 -9
  95. data/lib/canvas_sync/job_uniqueness/on_conflict/raise.rb +0 -11
  96. data/lib/canvas_sync/job_uniqueness/on_conflict/reject.rb +0 -21
  97. data/lib/canvas_sync/job_uniqueness/on_conflict/reschedule.rb +0 -20
  98. data/lib/canvas_sync/job_uniqueness/on_conflict.rb +0 -62
  99. data/lib/canvas_sync/job_uniqueness/strategy/base.rb +0 -107
  100. data/lib/canvas_sync/job_uniqueness/strategy/until_and_while_executing.rb +0 -35
  101. data/lib/canvas_sync/job_uniqueness/strategy/until_executed.rb +0 -20
  102. data/lib/canvas_sync/job_uniqueness/strategy/until_executing.rb +0 -20
  103. data/lib/canvas_sync/job_uniqueness/strategy/until_expired.rb +0 -16
  104. data/lib/canvas_sync/job_uniqueness/strategy/while_executing.rb +0 -26
  105. data/lib/canvas_sync/job_uniqueness/strategy.rb +0 -27
  106. data/lib/canvas_sync/job_uniqueness/unique_job_common.rb +0 -79
  107. data/spec/dummy/README.rdoc +0 -1
  108. data/spec/dummy/Rakefile +0 -6
  109. data/spec/dummy/app/services/live_events/assignment_created_event.rb +0 -12
  110. data/spec/dummy/app/services/live_events/assignment_updated_event.rb +0 -12
  111. data/spec/dummy/app/services/live_events/base_event.rb +0 -52
  112. data/spec/dummy/app/services/live_events/course_created_event.rb +0 -12
  113. data/spec/dummy/app/services/live_events/course_section_created_event.rb +0 -12
  114. data/spec/dummy/app/services/live_events/course_section_updated_event.rb +0 -12
  115. data/spec/dummy/app/services/live_events/course_updated_event.rb +0 -12
  116. data/spec/dummy/app/services/live_events/enrollment_created_event.rb +0 -12
  117. data/spec/dummy/app/services/live_events/enrollment_updated_event.rb +0 -12
  118. data/spec/dummy/app/services/live_events/grade_changed_event.rb +0 -12
  119. data/spec/dummy/app/services/live_events/module_created_event.rb +0 -12
  120. data/spec/dummy/app/services/live_events/module_item_created_event.rb +0 -12
  121. data/spec/dummy/app/services/live_events/module_item_updated_event.rb +0 -12
  122. data/spec/dummy/app/services/live_events/module_updated_event.rb +0 -12
  123. data/spec/dummy/app/services/live_events/submission_created_event.rb +0 -12
  124. data/spec/dummy/app/services/live_events/submission_updated_event.rb +0 -12
  125. data/spec/dummy/app/services/live_events/syllabus_updated_event.rb +0 -12
  126. data/spec/dummy/app/services/live_events/user_created_event.rb +0 -12
  127. data/spec/dummy/app/services/live_events/user_updated_event.rb +0 -12
  128. data/spec/dummy/bin/rails +0 -4
  129. data/spec/dummy/config/application.rb +0 -39
  130. data/spec/dummy/config/boot.rb +0 -5
  131. data/spec/dummy/config/database.yml +0 -25
  132. data/spec/dummy/config/environment.rb +0 -5
  133. data/spec/dummy/config/environments/development.rb +0 -41
  134. data/spec/dummy/config/environments/test.rb +0 -44
  135. data/spec/dummy/config/initializers/assets.rb +0 -11
  136. data/spec/dummy/config/initializers/session_store.rb +0 -3
  137. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  138. data/spec/dummy/config/routes.rb +0 -3
  139. data/spec/dummy/config/secrets.yml +0 -22
  140. data/spec/dummy/config.ru +0 -4
  141. data/spec/dummy/db/schema.rb +0 -563
  142. data/spec/job_batching/batch_spec.rb +0 -531
  143. data/spec/job_batching/callback_spec.rb +0 -38
  144. data/spec/job_batching/compat/active_job_spec.rb +0 -107
  145. data/spec/job_batching/compat/sidekiq_spec.rb +0 -127
  146. data/spec/job_batching/context_hash_spec.rb +0 -54
  147. data/spec/job_batching/flow_spec.rb +0 -82
  148. data/spec/job_batching/integration/fail_then_succeed.rb +0 -42
  149. data/spec/job_batching/integration/integration.rb +0 -57
  150. data/spec/job_batching/integration/nested.rb +0 -88
  151. data/spec/job_batching/integration/simple.rb +0 -47
  152. data/spec/job_batching/integration/workflow.rb +0 -134
  153. data/spec/job_batching/integration_helper.rb +0 -50
  154. data/spec/job_batching/pool_spec.rb +0 -161
  155. data/spec/job_batching/status_spec.rb +0 -76
  156. data/spec/job_batching/support/base_job.rb +0 -14
  157. data/spec/job_batching/support/sample_callback.rb +0 -2
  158. data/spec/job_uniqueness/compat/active_job_spec.rb +0 -49
  159. data/spec/job_uniqueness/compat/sidekiq_spec.rb +0 -68
  160. data/spec/job_uniqueness/lock_context_spec.rb +0 -106
  161. data/spec/job_uniqueness/on_conflict/log_spec.rb +0 -11
  162. data/spec/job_uniqueness/on_conflict/raise_spec.rb +0 -10
  163. data/spec/job_uniqueness/on_conflict/reschedule_spec.rb +0 -63
  164. data/spec/job_uniqueness/on_conflict_spec.rb +0 -16
  165. data/spec/job_uniqueness/spec_helper.rb +0 -17
  166. data/spec/job_uniqueness/strategy/base_spec.rb +0 -100
  167. data/spec/job_uniqueness/strategy/until_and_while_executing_spec.rb +0 -48
  168. data/spec/job_uniqueness/strategy/until_executed_spec.rb +0 -23
  169. data/spec/job_uniqueness/strategy/until_executing_spec.rb +0 -23
  170. data/spec/job_uniqueness/strategy/until_expired_spec.rb +0 -23
  171. data/spec/job_uniqueness/strategy/while_executing_spec.rb +0 -33
  172. data/spec/job_uniqueness/support/lock_strategy.rb +0 -28
  173. data/spec/job_uniqueness/support/on_conflict.rb +0 -24
  174. data/spec/job_uniqueness/support/test_worker.rb +0 -19
  175. data/spec/job_uniqueness/unique_job_common_spec.rb +0 -45
  176. /data/spec/{dummy → internal}/app/models/account.rb +0 -0
  177. /data/spec/{dummy → internal}/app/models/admin.rb +0 -0
  178. /data/spec/{dummy → internal}/app/models/assignment.rb +0 -0
  179. /data/spec/{dummy → internal}/app/models/assignment_group.rb +0 -0
  180. /data/spec/{dummy → internal}/app/models/assignment_override.rb +0 -0
  181. /data/spec/{dummy → internal}/app/models/context_module.rb +0 -0
  182. /data/spec/{dummy → internal}/app/models/context_module_item.rb +0 -0
  183. /data/spec/{dummy → internal}/app/models/course_progress.rb +0 -0
  184. /data/spec/{dummy → internal}/app/models/enrollment.rb +0 -0
  185. /data/spec/{dummy → internal}/app/models/grading_period.rb +0 -0
  186. /data/spec/{dummy → internal}/app/models/grading_period_group.rb +0 -0
  187. /data/spec/{dummy → internal}/app/models/group.rb +0 -0
  188. /data/spec/{dummy → internal}/app/models/group_membership.rb +0 -0
  189. /data/spec/{dummy → internal}/app/models/learning_outcome_result.rb +0 -0
  190. /data/spec/{dummy → internal}/app/models/pseudonym.rb +0 -0
  191. /data/spec/{dummy → internal}/app/models/role.rb +0 -0
  192. /data/spec/{dummy → internal}/app/models/rubric.rb +0 -0
  193. /data/spec/{dummy → internal}/app/models/rubric_assessment.rb +0 -0
  194. /data/spec/{dummy → internal}/app/models/rubric_association.rb +0 -0
  195. /data/spec/{dummy → internal}/app/models/score.rb +0 -0
  196. /data/spec/{dummy → internal}/app/models/section.rb +0 -0
  197. /data/spec/{dummy → internal}/app/models/submission.rb +0 -0
  198. /data/spec/{dummy → internal}/app/models/term.rb +0 -0
  199. /data/spec/{dummy → internal}/app/models/user.rb +0 -0
  200. /data/spec/{dummy → internal}/app/models/user_observer.rb +0 -0
  201. /data/spec/{dummy/db/migrate/20190702203621_create_courses.rb → internal/db/migrate/20250912205138_create_courses.rb} +0 -0
  202. /data/spec/{dummy/db/migrate/20190702203624_create_enrollments.rb → internal/db/migrate/20250912205143_create_enrollments.rb} +0 -0
  203. /data/spec/{dummy/db/migrate/20250319194134_create_course_nicknames.rb → internal/db/migrate/20250912205158_create_course_nicknames.rb} +0 -0
  204. /data/spec/{dummy/db/migrate/20250319194135_create_rubrics.rb → internal/db/migrate/20250912205159_create_rubrics.rb} +0 -0
  205. /data/spec/{dummy/db/migrate/20241223080202_create_assignment_overrides.rb → internal/db/migrate/20250912205163_create_assignment_overrides.rb} +0 -0
  206. /data/spec/{dummy/db/migrate/20250626194330_create_scores.rb → internal/db/migrate/20250912205164_create_scores.rb} +0 -0
@@ -1,218 +0,0 @@
1
-
2
- begin
3
- require "sidekiq/web"
4
- rescue LoadError
5
- # client-only usage
6
- end
7
-
8
- require_relative "web/helpers"
9
-
10
- module CanvasSync::JobBatches::Compat::Sidekiq
11
- module Web
12
- DEV_MODE = (defined?(Rails) && !Rails.env.production?) || !!ENV["SIDEKIQ_WEB_TESTING"]
13
- Sidekiq::WebHelpers::SAFE_QPARAMS << 'all_batches'
14
- Sidekiq::WebHelpers::SAFE_QPARAMS << 'count'
15
-
16
- def self.registered(app) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
17
- app.helpers do
18
- include Web::Helpers
19
-
20
- def dev_mode?
21
- DEV_MODE
22
- end
23
- end
24
-
25
- # =============== BATCHES =============== #
26
-
27
- app.get "/batches" do
28
- @count = (params['count'] || 25).to_i
29
-
30
- source_key = params['all_batches'] ? "batches" : "BID-ROOT-bids"
31
- @current_page, @total_size, @batches = page(source_key, params['page'], @count)
32
- @batches = @batches.map {|b, score| CanvasSync::JobBatches::Batch.new(b) }
33
-
34
- erb(get_template(:batches))
35
- end
36
-
37
- app.get "/batches/:bid" do
38
- @bid = params[:bid]
39
- @batch = CanvasSync::JobBatches::Batch.new(@bid)
40
-
41
- @tree_data = tree_data(@bid)
42
-
43
- @count = (params['count'] || 25).to_i
44
- @current_batches_page, @total_batches_size, @sub_batches = page("BID-#{@batch.bid}-bids", params['batch_page'], @count)
45
- @sub_batches = @sub_batches.map {|b, score| CanvasSync::JobBatches::Batch.new(b) }
46
-
47
- @current_jobs_page, @total_jobs_size, @jobs = page("BID-#{@batch.bid}-jids", params['job_page'], @count)
48
- @jobs = @jobs.map do |jid, score|
49
- { jid: jid, }
50
- end
51
-
52
- erb(get_template(:batch))
53
- end
54
-
55
- app.get "/batches/:bid/tree" do
56
- @bid = params[:bid]
57
-
58
- json(tree_data(@bid, slice: params[:slice]))
59
- end
60
-
61
- app.helpers do
62
- def tree_data(root_bid, slice: nil)
63
- tree_bids = CanvasSync::JobBatches::Batch.bid_hierarchy(root_bid, slice: slice)
64
-
65
- CanvasSync::JobBatches::Batch.redis do |r|
66
- layer_data = ->(layer, parent = nil) {
67
- bid = layer[0]
68
- batch = CanvasSync::JobBatches::Batch.new(bid)
69
-
70
- jobs_total = r.hget("BID-#{bid}", "job_count").to_i
71
- jobs_pending = r.hget("BID-#{bid}", 'pending').to_i
72
- jobs_failed = r.scard("BID-#{bid}-failed").to_i
73
- jobs_dead = r.scard("BID-#{bid}-dead").to_i
74
- jobs_success = jobs_total - jobs_pending
75
-
76
- batches_total = r.hget("BID-#{bid}", 'children').to_i
77
- batches_success = r.scard("BID-#{bid}-batches-success").to_i
78
- batches_pending = batches_total - batches_success
79
- batches_failed = r.scard("BID-#{bid}-batches-failed").to_i
80
-
81
- status = 'in_progress'
82
- status = 'complete' if batches_pending == batches_failed && jobs_pending == jobs_failed
83
- status = 'success' if batches_pending == 0 && jobs_pending == 0
84
- status = 'deleted' if bid != root_bid && !batch.parent_bid
85
-
86
- {
87
- bid: bid,
88
- created_at: r.hget("BID-#{bid}", 'created_at'),
89
- status: status,
90
- parent_bid: parent ? parent.bid : batch.parent_bid,
91
- description: batch.description,
92
- jobs: {
93
- pending_count: jobs_pending,
94
- successful_count: jobs_success,
95
- failed_count: jobs_failed,
96
- dead_count: jobs_dead,
97
- total_count: jobs_total,
98
- # items: batches.map{|b| layer_data[b] },
99
- },
100
- batches: {
101
- pending_count: batches_pending,
102
- successful_count: batches_success,
103
- failed_count: batches_failed,
104
- total_count: batches_total,
105
- items: layer[1].map{|b| layer_data[b, batch] },
106
- },
107
- }
108
- }
109
-
110
- data = layer_data[tree_bids]
111
- data[:batches][:slice] = slice if slice
112
- data
113
- end
114
- end
115
-
116
- def format_context(batch)
117
- bits = []
118
- own_keys = batch.context.own.keys
119
- batch.context.flatten.each do |k,v|
120
- added = own_keys.include? k
121
- bits << " <span class=\"key #{added ? 'own' : 'inherited'}\">\"#{k}\": #{v.to_json},</span>"
122
- end
123
- bits = [
124
- "{ // <span class=\"own\">Added</span> / <span class=\"inherited\">Inherited</span>",
125
- *bits,
126
- '}'
127
- ]
128
- bits.join("\n")
129
- end
130
- end
131
-
132
- app.post "/batches/all" do
133
- if params['delete']
134
- index_key = CanvasSync::JobBatches::Batch::INDEX_ALL_BATCHES ? "batches" : "BID-ROOT-bids"
135
- drain_zset(index_key) do |batches|
136
- batches.each do |bid|
137
- CanvasSync::JobBatches::Batch.cleanup_redis(bid)
138
- end
139
- end
140
- end
141
-
142
- redirect "#{root_path}batches"
143
- end
144
-
145
- app.post "/batches/:bid" do
146
- @bid = params[:bid]
147
- @batch = CanvasSync::JobBatches::Batch.new(@bid)
148
-
149
- if params['delete']
150
- CanvasSync::JobBatches::Batch.delete_prematurely!(@bid)
151
- end
152
-
153
- redirect_with_query("#{root_path}batches")
154
- end
155
-
156
- # =============== POOLS =============== #
157
-
158
- app.get "/pools" do
159
- @count = (params['count'] || 25).to_i
160
- @current_page, @total_size, @pools = page('pools', params['page'], @count)
161
- @pools = @pools.map {|b, score| CanvasSync::JobBatches::Pool.new(b) }
162
-
163
- erb(get_template(:pools))
164
- end
165
-
166
- app.get "/pools/:pid" do
167
- @pid = params[:pid]
168
- @pool = CanvasSync::JobBatches::Pool.new(@pid)
169
-
170
- @active_tasks = @pool.active_jobs
171
-
172
- @count = (params['count'] || 25).to_i
173
- @current_jobs_page, @total_jobs_size, @jobs = page("POOLID-#{@pool.pid}-jobs", params['job_page'], @count)
174
- @jobs = @jobs.map {|desc, score=nil| JSON.parse(desc)[0] }
175
-
176
- erb(get_template(:pool))
177
- end
178
-
179
- app.post "/pools/all" do
180
- if params['delete']
181
- drain_zset('pools') do |pools|
182
- pools.each do |pid|
183
- CanvasSync::JobBatches::Pool.from_pid(pid).cleanup_redis
184
- end
185
- end
186
- end
187
-
188
- redirect "#{root_path}pools"
189
- end
190
-
191
- app.post "/pools/:pid" do
192
- @pid = params[:pid]
193
- @pool = CanvasSync::JobBatches::Pool.from_pid(@pid)
194
-
195
- if params['delete']
196
- @pool.cleanup_redis
197
- end
198
-
199
- redirect_with_query("#{root_path}pools")
200
- end
201
- end
202
- end
203
- end
204
-
205
- if defined?(::Sidekiq::Web)
206
- rules = []
207
- rules = [[:all, {"Cache-Control" => "public, max-age=86400"}]] unless CanvasSync::JobBatches::Compat::Sidekiq::Web::DEV_MODE
208
-
209
- ::Sidekiq::Web.use Rack::Static, urls: ["/batches_assets"],
210
- root: File.expand_path("#{File.dirname(__FILE__)}/web"),
211
- cascade: true,
212
- header_rules: rules
213
-
214
- ::Sidekiq::Web.register CanvasSync::JobBatches::Compat::Sidekiq::Web
215
- ::Sidekiq::Web.tabs["Batches"] = "batches"
216
- ::Sidekiq::Web.tabs["Pools"] = "pools"
217
- ::Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), "locales")
218
- end
@@ -1,149 +0,0 @@
1
- begin
2
- require 'sidekiq/batch'
3
- rescue LoadError
4
- end
5
-
6
- module CanvasSync::JobBatches
7
- module Compat
8
- module Sidekiq
9
- module WorkerExtension
10
- def bid
11
- Thread.current[CURRENT_BATCH_THREAD_KEY].bid
12
- end
13
-
14
- def batch
15
- Thread.current[CURRENT_BATCH_THREAD_KEY]
16
- end
17
-
18
- def batch_context
19
- batch&.context || {}
20
- end
21
-
22
- def valid_within_batch?
23
- batch.valid?
24
- end
25
- end
26
-
27
- class SidekiqCallbackWorker
28
- include ::Sidekiq::Worker
29
- include WorkerExtension
30
- include Batch::Callback::CallbackWorkerCommon
31
-
32
- def self.enqueue_all(args, queue)
33
- return if args.empty?
34
-
35
- ::Sidekiq::Client.push_bulk(
36
- 'class' => self,
37
- 'args' => args,
38
- 'queue' => queue
39
- )
40
- end
41
- end
42
-
43
- class ClientMiddleware
44
- include ::Sidekiq::ClientMiddleware if defined? ::Sidekiq::ClientMiddleware
45
-
46
- def call(_worker, msg, _queue, _redis_pool = nil)
47
- if (batch = Thread.current[CURRENT_BATCH_THREAD_KEY]) && should_handle_batch?(msg)
48
- batch.append_jobs(msg['jid']) if (msg['bid'] = batch.bid)
49
- end
50
- yield
51
- end
52
-
53
- def should_handle_batch?(msg)
54
- return false if CanvasSync::JobBatches::Compat::Sidekiq.is_activejob_job?(msg)
55
- true
56
- end
57
- end
58
-
59
- class ServerMiddleware
60
- include ::Sidekiq::ServerMiddleware if defined? ::Sidekiq::ServerMiddleware
61
-
62
- def call(_worker, msg, _queue)
63
- if (bid = msg['bid'])
64
- prev_batch = Thread.current[CURRENT_BATCH_THREAD_KEY]
65
- begin
66
- Thread.current[CURRENT_BATCH_THREAD_KEY] = Batch.new(bid)
67
- yield
68
- Thread.current[CURRENT_BATCH_THREAD_KEY].save_context_changes
69
- Batch.process_successful_job(bid, msg['jid'])
70
- rescue
71
- Batch.process_failed_job(bid, msg['jid'])
72
- raise
73
- ensure
74
- Thread.current[CURRENT_BATCH_THREAD_KEY] = prev_batch
75
- end
76
- else
77
- yield
78
- end
79
- end
80
- end
81
-
82
- def self.is_activejob_job?(msg)
83
- return false unless defined?(::ActiveJob)
84
-
85
- msg['class'] == 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper' && (msg['wrapped'].to_s).constantize < CanvasSync::JobBatches::Compat::ActiveJob::BatchAwareJob
86
- end
87
-
88
- def self.switch_tenant(job)
89
- if defined?(::Apartment)
90
- ::Apartment::Tenant.switch(job['apartment'] || 'public') do
91
- yield
92
- end
93
- else
94
- yield
95
- end
96
- end
97
-
98
- def self.sidekiq_middleware(placement, &blk)
99
- install_middleware = ->(config) do
100
- config.send("#{placement}_middleware") do |chain|
101
- blk.call(chain)
102
- end
103
- end
104
-
105
- ::Sidekiq.configure_client(&install_middleware) if placement == :client
106
- ::Sidekiq.configure_server(&install_middleware)
107
- end
108
-
109
- def self.configure
110
- return if @already_configured
111
- @already_configured = true
112
-
113
- if defined?(::Sidekiq::Batch) && ::Sidekiq::Batch != CanvasSync::JobBatches::Batch
114
- print "WARNING: Detected Sidekiq Pro or sidekiq-batch. CanvasSync JobBatches may not be fully compatible!"
115
- end
116
-
117
- sidekiq_middleware(:client) do |chain|
118
- chain.remove ::Sidekiq::Batch::Middleware::ClientMiddleware if defined?(::Sidekiq::Batch::Middleware::ClientMiddleware)
119
- chain.add CanvasSync::JobBatches::Compat::Sidekiq::ClientMiddleware
120
- end
121
-
122
- sidekiq_middleware(:server) do |chain|
123
- chain.remove ::Sidekiq::Batch::Middleware::ServerMiddleware if defined?(::Sidekiq::Batch::Middleware::ServerMiddleware)
124
- chain.add CanvasSync::JobBatches::Compat::Sidekiq::ServerMiddleware
125
- end
126
-
127
- ::Sidekiq.configure_server do |config|
128
- config.death_handlers << ->(job, ex) do
129
- switch_tenant(job) do
130
- if is_activejob_job?(job)
131
- CanvasSync::JobBatches::Compat::ActiveJob.handle_job_death(job["args"][0], ex)
132
- elsif job['bid'].present?
133
- ::Sidekiq::Batch.process_dead_job(job['bid'], job['jid'])
134
- end
135
- end
136
- end
137
- end
138
-
139
- ::Sidekiq.const_set(:Batch, CanvasSync::JobBatches::Batch)
140
- # This alias helps apartment-sidekiq set itself up correctly
141
- ::Sidekiq::Batch.const_set(:Server, CanvasSync::JobBatches::Compat::Sidekiq::ServerMiddleware)
142
- ::Sidekiq::Worker.send(:include, CanvasSync::JobBatches::Compat::Sidekiq::WorkerExtension)
143
- Batch::Callback.worker_class = SidekiqCallbackWorker
144
- end
145
- end
146
- end
147
- end
148
-
149
- require_relative 'sidekiq/web'
@@ -1,20 +0,0 @@
1
-
2
- module CanvasSync::JobBatches
3
- module Compat
4
- def self.load_compat(name)
5
- name = name.to_s
6
- begin
7
- require name
8
- rescue LoadError
9
- end
10
-
11
- if name.classify.safe_constantize
12
- require_relative "./compat/#{name}"
13
- "CanvasSync::JobBatches::Compat::#{name.classify}".constantize.configure
14
- end
15
- end
16
-
17
- load_compat(:active_job)
18
- load_compat(:sidekiq)
19
- end
20
- end
@@ -1,157 +0,0 @@
1
- module CanvasSync::JobBatches
2
- class ContextHash
3
- delegate_missing_to :flatten
4
-
5
- def initialize(bid, hash = nil)
6
- @bid_stack = [bid]
7
- @hash_map = {}
8
- @dirty = false
9
- @flattened = nil
10
- @hash_map[bid] = hash.with_indifferent_access if hash
11
- end
12
-
13
- # Local is "the nearest batch with a context value"
14
- # This allows for, for example, SerialBatchJob to have a modifiable context stored on it's main Batch
15
- # that can be accessed transparently from one of it's internal, context-less Batches
16
- def local_bid
17
- bid = @bid_stack[-1]
18
- while bid.present?
19
- bhash = resolve_hash(bid)
20
- return bid if bhash
21
- bid = get_parent_bid(bid)
22
- end
23
- nil
24
- end
25
-
26
- def local
27
- @hash_map[local_bid]
28
- end
29
-
30
- def own
31
- resolve_hash(@bid_stack[-1]) || {}
32
- end
33
-
34
- def set_local(new_hash)
35
- @dirty = true
36
- local.clear.merge!(new_hash)
37
- end
38
-
39
- def clear
40
- local.clear
41
- @flattened = nil
42
- @dirty = true
43
- self
44
- end
45
-
46
- def []=(key, value)
47
- @flattened = nil
48
- @dirty = true
49
- local[key] = value
50
- end
51
-
52
- def [](key)
53
- bid = @bid_stack[-1]
54
- while bid.present?
55
- bhash = resolve_hash(bid)
56
- return bhash[key] if bhash&.key?(key)
57
- bid = get_parent_bid(bid)
58
- end
59
- nil
60
- end
61
-
62
- def reload!
63
- @dirty = false
64
- @hash_map = {}
65
- self
66
- end
67
-
68
- def save!(force: false)
69
- return unless dirty? || force
70
- Batch.redis do |r|
71
- r.hset("BID-#{local_bid}", 'context', JSON.unparse(local))
72
- end
73
- end
74
-
75
- def dirty?
76
- @dirty
77
- end
78
-
79
- def is_a?(arg)
80
- return true if Hash <= arg
81
- super
82
- end
83
-
84
- def flatten
85
- return @flattened if @flattened
86
-
87
- load_all
88
- flattened = {}
89
- @bid_stack.compact.each do |bid|
90
- flattened.merge!(@hash_map[bid]) if @hash_map[bid]
91
- end
92
- flattened.freeze
93
-
94
- @flattened = flattened.with_indifferent_access
95
- end
96
-
97
- def to_h
98
- flatten
99
- end
100
-
101
- private
102
-
103
- def get_parent_hash(bid)
104
- resolve_hash(get_parent_bid(bid)).freeze
105
- end
106
-
107
- def get_parent_bid(bid)
108
- index = @bid_stack.index(bid)
109
- raise "Invalid BID #{bid}" if index.nil? # Sanity Check - this shouldn't happen
110
-
111
- index -= 1
112
- if index >= 0
113
- @bid_stack[index]
114
- else
115
- pbid = Batch.redis do |r|
116
- callback_params = JSON.parse(r.hget("BID-#{bid}", "callback_params") || "{}")
117
- callback_params['for_bid'] || r.hget("BID-#{bid}", "parent_bid")
118
- end
119
- @bid_stack.unshift(pbid)
120
- pbid
121
- end
122
- end
123
-
124
- def resolve_hash(bid)
125
- return nil unless bid.present?
126
- return @hash_map[bid] if @hash_map.key?(bid)
127
-
128
- context_json, editable = Batch.redis do |r|
129
- r.multi do |r|
130
- r.hget("BID-#{bid}", "context")
131
- r.hget("BID-#{bid}", "allow_context_changes")
132
- end
133
- end
134
-
135
- if context_json.present?
136
- context_hash = JSON.parse(context_json)
137
- context_hash = context_hash.with_indifferent_access
138
- context_hash.each do |k, v|
139
- v.freeze
140
- end
141
- context_hash.freeze unless editable
142
-
143
- @hash_map[bid] = context_hash
144
- else
145
- @hash_map[bid] = nil
146
- end
147
- end
148
-
149
- def load_all
150
- resolve_hash(@bid_stack[0]).freeze
151
- while @bid_stack[0].present?
152
- get_parent_hash(@bid_stack[0])
153
- end
154
- @hash_map
155
- end
156
- end
157
- end
@@ -1,25 +0,0 @@
1
-
2
- local function add_bids(root, depth)
3
- local result_data = {}
4
-
5
- if depth > 0 then
6
- local sbids
7
- if depth == tonumber(ARGV[2]) and ARGV[4] then
8
- local min, max = ARGV[4]:match('(%d+):(%d+)')
9
- sbids = redis.call('ZRANGE', 'BID-' .. root .. '-bids', min, max)
10
- else
11
- sbids = redis.call('ZRANGE', 'BID-' .. root .. '-bids', 0, tonumber(ARGV[3]) - 1)
12
- end
13
-
14
- local sub_data = {}
15
- for _,v in ipairs(sbids) do
16
- table.insert(sub_data, add_bids(v, depth - 1))
17
- end
18
-
19
- return { root, sub_data }
20
- end
21
-
22
- return { root, result_data}
23
- end
24
-
25
- return add_bids(ARGV[1], tonumber(ARGV[2]))
@@ -1,5 +0,0 @@
1
- module CanvasSync::JobBatches
2
- class BaseJob < ::ActiveJob::Base
3
-
4
- end
5
- end
@@ -1,20 +0,0 @@
1
- require_relative './base_job'
2
-
3
- module CanvasSync::JobBatches
4
- class ConcurrentBatchJob < BaseJob
5
- def self.make_batch(sub_jobs, **kwargs, &blk)
6
- ManagedBatchJob.make_batch(
7
- sub_jobs,
8
- concurrency: true,
9
- **kwargs,
10
- ordered: false,
11
- desc_prefix: 'ConcurrentBatchJob: ',
12
- &blk
13
- )
14
- end
15
-
16
- def perform(sub_jobs, **kwargs)
17
- self.class.make_batch(sub_jobs, **kwargs)
18
- end
19
- end
20
- end