Class: Hyperloop::InternalPolicy

Inherits:
Object
  • Object
show all
Defined in:
lib/hyper-operation/transport/policy.rb

Constant Summary collapse

EXPOSED_METHODS =
[:send_all, :send_all_but, :send_only, :obj]

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(obj, attribute_names, available_channels) ⇒ InternalPolicy

Returns a new instance of InternalPolicy.



409
410
411
412
413
414
415
# File 'lib/hyper-operation/transport/policy.rb', line 409

def initialize(obj, attribute_names, available_channels)
  @obj = obj
  attribute_names = attribute_names.map(&:to_sym).to_set
  @unassigned_send_sets = []
  @channel_sets = Hash.new { |hash, key| hash[key] = attribute_names }
  @available_channels = available_channels
end

Class Method Details

.channel_to_string(channel) ⇒ Object



459
460
461
462
463
464
465
466
467
# File 'lib/hyper-operation/transport/policy.rb', line 459

def self.channel_to_string(channel)
  if channel.is_a?(Class) && channel.name
    channel.name
  elsif channel.is_a? String
    channel
  else
    "#{channel.class.name}-#{channel.id}"
  end
end

.raise_operation_access_violation(message, details) ⇒ Object



381
382
383
384
# File 'lib/hyper-operation/transport/policy.rb', line 381

def self.raise_operation_access_violation(message, details)
  Hyperloop.on_error(Hyperloop::AccessViolation, message, details)
  raise Hyperloop::AccessViolation
end

.regulate_broadcast(model, &block) ⇒ Object



400
401
402
403
404
405
406
407
# File 'lib/hyper-operation/transport/policy.rb', line 400

def self.regulate_broadcast(model, &block)
  internal_policy = InternalPolicy.new(
    model, model.attribute_names, Connection.active
  )
  ChannelBroadcastRegulation.broadcast(internal_policy)
  InstanceBroadcastRegulation.broadcast(model, internal_policy)
  internal_policy.broadcast &block
end

.regulate_connection(acting_user, channel_string) ⇒ Object



386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/hyper-operation/transport/policy.rb', line 386

def self.regulate_connection(acting_user, channel_string)
  channel = channel_string.split("-")
  if channel.length > 1
    id = channel[1..-1].join("-")
    unless Hyperloop::InternalClassPolicy.regulated_klasses.include?(channel[0])
      Hyperloop::InternalPolicy.raise_operation_access_violation(:not_a_channel, "#{channel[0]} is not regulated channel class")
    end
    object = Object.const_get(channel[0]).find(id)
    InstanceConnectionRegulation.connect(object, acting_user)
  else
    ClassConnectionRegulation.connect(channel[0], acting_user)
  end
end

Instance Method Details

#add_unassigned_send_set(send_set) ⇒ Object



438
439
440
# File 'lib/hyper-operation/transport/policy.rb', line 438

def add_unassigned_send_set(send_set)
  @unassigned_send_sets << send_set
end

#broadcast(&block) ⇒ Object



495
496
497
498
499
500
501
# File 'lib/hyper-operation/transport/policy.rb', line 495

def broadcast(&block)
  klass = @obj.class
  header = {broadcast_id: id, channels: channel_list, klass: klass.name}
  @channel_sets.each do |channel, attribute_set|
    send_message header, channel, attribute_set, &block
  end
end

#channel_available?(channel) ⇒ Boolean

Returns:

  • (Boolean)


417
418
419
# File 'lib/hyper-operation/transport/policy.rb', line 417

def channel_available?(channel)
  channel && @available_channels.include?(channel_to_string(channel))
end

#channel_listObject



455
456
457
# File 'lib/hyper-operation/transport/policy.rb', line 455

def channel_list
  @channel_sets.collect { |channel, _value| channel_to_string channel }
end

#channel_to_string(channel) ⇒ Object



469
470
471
# File 'lib/hyper-operation/transport/policy.rb', line 469

def channel_to_string(channel)
  self.class.channel_to_string(channel)
end

#filter(h, attribute_set) ⇒ Object



473
474
475
476
477
478
479
480
481
# File 'lib/hyper-operation/transport/policy.rb', line 473

def filter(h, attribute_set)
  r = {}
  h.each do |key, value|
    r[key.to_sym] = value if attribute_set.member?(key.to_sym) || (key.to_sym == :id)
  end unless attribute_set.empty?
  #model_id = h[:id] || h["id"]
  #r[:id] = model_id if model_id && !attribute_set.empty?
  r
end

#has_unassigned_sets?Boolean

Returns:

  • (Boolean)


425
426
427
# File 'lib/hyper-operation/transport/policy.rb', line 425

def has_unassigned_sets?
  !@unassigned_send_sets.empty?
end

#idObject



421
422
423
# File 'lib/hyper-operation/transport/policy.rb', line 421

def id
  @id ||= "#{self.object_id}-#{Time.now.to_f}"
end

#merge_set(send_set, channel) ⇒ Object



449
450
451
452
453
# File 'lib/hyper-operation/transport/policy.rb', line 449

def merge_set(send_set, channel)
  return unless channel
  channel = channel.name if channel.is_a?(Class) && channel.name
  @channel_sets[channel] = send_set.merge(@channel_sets[channel])
end

#objObject



377
378
379
# File 'lib/hyper-operation/transport/policy.rb', line 377

def obj
  @obj
end

#send_allObject



365
366
367
# File 'lib/hyper-operation/transport/policy.rb', line 365

def send_all
  SendSet.new(self)
end

#send_all_but(*execeptions) ⇒ Object



369
370
371
# File 'lib/hyper-operation/transport/policy.rb', line 369

def send_all_but(*execeptions)
  SendSet.new(self, exclude: execeptions)
end

#send_message(header, channel, attribute_set) {|message| ... } ⇒ Object

Yields:

  • (message)


483
484
485
486
487
488
489
490
491
492
493
# File 'lib/hyper-operation/transport/policy.rb', line 483

def send_message(header, channel, attribute_set, &block)
  record = filter(@obj.react_serializer, attribute_set)
  previous_changes = filter(@obj.previous_changes, attribute_set)
  return if record.empty? && previous_changes.empty?
  message = header.merge(
    channel: channel_to_string(channel),
    record: record,
    previous_changes: previous_changes
  )
  yield message
end

#send_only(*white_list) ⇒ Object



373
374
375
# File 'lib/hyper-operation/transport/policy.rb', line 373

def send_only(*white_list)
  SendSet.new(self, white_list: white_list)
end

#send_set_to(send_set, channels) ⇒ Object



442
443
444
445
446
447
# File 'lib/hyper-operation/transport/policy.rb', line 442

def send_set_to(send_set, channels)
  channels.flatten(1).each do |channel|
    merge_set(send_set, channel) if channel_available? channel
    @unassigned_send_sets.delete(send_set)
  end
end

#send_unassigned_sets_to(channel) ⇒ Object



429
430
431
432
433
434
435
436
# File 'lib/hyper-operation/transport/policy.rb', line 429

def send_unassigned_sets_to(channel)
  if channel_available?(channel) && has_unassigned_sets?
    @channel_sets[channel] = @unassigned_send_sets.inject(@channel_sets[channel]) do |set, send_set|
      send_set.merge(set)
    end
  end
  @unassigned_send_sets = []
end