activity_notification 2.5.0 → 2.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ac9e17e63d801b74604936ea099825e1eedd68c5f743b35c01e7af9e73d90ab
4
- data.tar.gz: 07db03884cf03f86db283a7b5cbd92f7629277ea5f4f5a910629924471ff62e3
3
+ metadata.gz: 30af4a0429874914d32df8bdff256add7d9278b9f19bbd9c3a03f23138dac654
4
+ data.tar.gz: f08926e67ff5a91cfa3e80bc94af31bf4e7d19f2fb1198a75fa2d906a69bc17e
5
5
  SHA512:
6
- metadata.gz: 91e6206957623ce19971e581afa07fe3b464b02273a968c17bbf145da5836aecbd9b0919b05fae844f912a003a9eeb0d2d4a1df011889ba6bcfb7d752c632346
7
- data.tar.gz: 0efe5572854a47c271f6b79b1e0ad649b0d491c1ba4b5370a09a78a0876b4f684bf841069fbaba26fff24e3735ae6b11eeb9bf92ce75f359776d59fd526519ce
6
+ metadata.gz: ea7191de6c42a8898d63462595f3f46dc48f3d3cbc10c54e1fad225fcab8d3bb5be15d4c05015ff800a8e4090e2080f1943fa3d72d956b2b7a5404d6a88fe7b1
7
+ data.tar.gz: 85cfb749ccab3170964b270f405d24d6d715dc2d1f808ec95e18a8ce0fd14a30250cf83b3985869996358339b5b2b00807bd9b993599a034271288cecc9914ee
@@ -231,7 +231,8 @@ module ActivityNotification
231
231
  notify_later(target_type, notifiable, options)
232
232
  else
233
233
  targets = notifiable.notification_targets(target_type, options[:pass_full_options] ? options : options[:key])
234
- unless targets.blank?
234
+ # Optimize blank check to avoid loading all records for ActiveRecord relations
235
+ unless targets_empty?(targets)
235
236
  notify_all(targets, notifiable, options)
236
237
  end
237
238
  end
@@ -272,10 +273,17 @@ module ActivityNotification
272
273
 
273
274
  # Generates notifications to specified targets.
274
275
  #
275
- # @example Notify to all users
276
+ # For large target collections, this method uses batch processing to reduce memory consumption:
277
+ # - ActiveRecord::Relation: Uses find_each (loads in batches of 1000 records)
278
+ # - Mongoid::Criteria: Uses each with cursor batching
279
+ # - Arrays: Standard iteration (already in memory)
280
+ #
281
+ # @example Notify to all users (with ActiveRecord relation for memory efficiency)
276
282
  # ActivityNotification::Notification.notify_all User.all, @comment
283
+ # @example Notify to all users with custom batch size
284
+ # ActivityNotification::Notification.notify_all User.all, @comment, batch_size: 500
277
285
  #
278
- # @param [Array<Object>] targets Targets to send notifications
286
+ # @param [ActiveRecord::Relation, Mongoid::Criteria, Array<Object>] targets Targets to send notifications
279
287
  # @param [Object] notifiable Notifiable instance
280
288
  # @param [Hash] options Options for notifications
281
289
  # @option options [String] :key (notifiable.default_notification_key) Key of the notification
@@ -287,23 +295,32 @@ module ActivityNotification
287
295
  # @option options [Boolean] :send_email (true) Whether it sends notification email
288
296
  # @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
289
297
  # @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
298
+ # @option options [Integer] :batch_size (1000) Batch size for ActiveRecord find_each (optional)
290
299
  # @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
291
300
  # @return [Array<Notificaion>] Array of generated notifications
292
301
  def notify_all(targets, notifiable, options = {})
293
302
  if options[:notify_later]
294
303
  notify_all_later(targets, notifiable, options)
295
304
  else
296
- targets.map { |target| notify_to(target, notifiable, options) }
305
+ # Optimize for large ActiveRecord relations by using batch processing
306
+ process_targets_in_batches(targets, notifiable, options)
297
307
  end
298
308
  end
299
309
  alias_method :notify_all_now, :notify_all
300
310
 
301
311
  # Generates notifications to specified targets later by ActiveJob queue.
302
312
  #
313
+ # Note: When passing ActiveRecord relations or Mongoid criteria to async jobs,
314
+ # they may be serialized to arrays before job execution, which can consume memory
315
+ # for large target sets. For very large datasets (10,000+ records), consider using
316
+ # notify_later with target_type instead, which generates notifications asynchronously
317
+ # without loading all targets upfront:
318
+ # ActivityNotification::Notification.notify(:users, @comment, notify_later: true)
319
+ #
303
320
  # @example Notify to all users later
304
321
  # ActivityNotification::Notification.notify_all_later User.all, @comment
305
322
  #
306
- # @param [Array<Object>] targets Targets to send notifications
323
+ # @param [ActiveRecord::Relation, Mongoid::Criteria, Array<Object>] targets Targets to send notifications
307
324
  # @param [Object] notifiable Notifiable instance
308
325
  # @param [Hash] options Options for notifications
309
326
  # @option options [String] :key (notifiable.default_notification_key) Key of the notification
@@ -549,6 +566,59 @@ module ActivityNotification
549
566
  notification.after_store
550
567
  notification
551
568
  end
569
+
570
+ # Checks if targets collection is empty without loading all records
571
+ # @api private
572
+ # @param [Object] targets Targets collection (can be an ActiveRecord::Relation, Mongoid::Criteria, Array, etc.)
573
+ # @return [Boolean] True if targets is empty
574
+ def targets_empty?(targets)
575
+ # For ActiveRecord relations and Mongoid criteria, use exists? to avoid loading all records
576
+ if targets.respond_to?(:exists?)
577
+ !targets.exists?
578
+ else
579
+ # For arrays and other enumerables, use blank?
580
+ targets.blank?
581
+ end
582
+ end
583
+
584
+ # Processes targets in batches for memory efficiency with large collections
585
+ # @api private
586
+ #
587
+ # For ActiveRecord::Relation, uses find_each which loads records in batches (default 1000).
588
+ # For Mongoid::Criteria, uses each which leverages MongoDB's cursor batching.
589
+ # For Arrays and other enumerables, uses standard iteration.
590
+ #
591
+ # Note: When called from async jobs (notify_all_later), ActiveRecord relations may be
592
+ # serialized to arrays before reaching this method, which limits batch processing benefits.
593
+ # Consider using notify_later with target_type instead of notify_all_later with relations
594
+ # for large datasets in async scenarios.
595
+ #
596
+ # @param [Object] targets Targets collection (can be an ActiveRecord::Relation, Mongoid::Criteria, Array, etc.)
597
+ # @param [Object] notifiable Notifiable instance
598
+ # @param [Hash] options Options for notifications
599
+ # @option options [Integer] :batch_size (1000) Batch size for ActiveRecord find_each (optional)
600
+ # @return [Array<Notification>] Array of generated notifications
601
+ def process_targets_in_batches(targets, notifiable, options = {})
602
+ notifications = []
603
+
604
+ # For ActiveRecord relations, use find_each to process in batches
605
+ # This loads records in batches (default 1000) to avoid loading all records into memory
606
+ if targets.respond_to?(:find_each)
607
+ batch_options = {}
608
+ batch_options[:batch_size] = options[:batch_size] if options[:batch_size]
609
+
610
+ targets.find_each(**batch_options) do |target|
611
+ notification = notify_to(target, notifiable, options)
612
+ notifications << notification
613
+ end
614
+ else
615
+ # For arrays and other enumerables, use standard map approach
616
+ # Already in memory, so no batching benefit
617
+ notifications = targets.map { |target| notify_to(target, notifiable, options) }
618
+ end
619
+
620
+ notifications
621
+ end
552
622
  end
553
623
 
554
624
  # :nocov:
@@ -1,3 +1,3 @@
1
1
  module ActivityNotification
2
- VERSION = "2.5.0"
2
+ VERSION = "2.5.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activity_notification
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shota Yamazaki
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-01-01 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: railties
@@ -19,7 +18,7 @@ dependencies:
19
18
  version: 7.0.0
20
19
  - - "<"
21
20
  - !ruby/object:Gem::Version
22
- version: '8.1'
21
+ version: '8.2'
23
22
  type: :runtime
24
23
  prerelease: false
25
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +28,7 @@ dependencies:
29
28
  version: 7.0.0
30
29
  - - "<"
31
30
  - !ruby/object:Gem::Version
32
- version: '8.1'
31
+ version: '8.2'
33
32
  - !ruby/object:Gem::Dependency
34
33
  name: i18n
35
34
  requirement: !ruby/object:Gem::Requirement
@@ -455,7 +454,6 @@ homepage: https://github.com/simukappu/activity_notification
455
454
  licenses:
456
455
  - MIT
457
456
  metadata: {}
458
- post_install_message:
459
457
  rdoc_options: []
460
458
  require_paths:
461
459
  - lib
@@ -470,8 +468,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
470
468
  - !ruby/object:Gem::Version
471
469
  version: '0'
472
470
  requirements: []
473
- rubygems_version: 3.5.22
474
- signing_key:
471
+ rubygems_version: 4.0.3
475
472
  specification_version: 4
476
473
  summary: Integrated user activity notifications for Ruby on Rails
477
474
  test_files: []