Class: Alki::Executor

Inherits:
Object
  • Object
show all
Defined in:
lib/alki/executor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instance) ⇒ Executor

Returns a new instance of Executor.



11
12
13
14
15
16
17
18
# File 'lib/alki/executor.rb', line 11

def initialize(instance)
  @semaphore = Concurrent::ReentrantReadWriteLock.new
  @lookup_cache = {}
  @call_cache = {}
  @context_cache = {}
  @data = nil
  @instance = instance
end

Instance Attribute Details

#metaObject

Returns the value of attribute meta.



9
10
11
# File 'lib/alki/executor.rb', line 9

def meta
  @meta
end

#rootObject

Returns the value of attribute root.



9
10
11
# File 'lib/alki/executor.rb', line 9

def root
  @root
end

Instance Method Details

#call(path, *args, &blk) ⇒ Object



26
27
28
# File 'lib/alki/executor.rb', line 26

def call(path,*args,&blk)
  execute({},path,args,blk)
end

#canonical_path(from, path) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/alki/executor.rb', line 45

def canonical_path(from,path)
  from_elem = lookup(from)
  scope = from_elem[:scope]
  path.inject(nil) do |p,elem|
    scope = lookup(p)[:scope] if p
    scope[elem]
  end
end

#execute(meta, path, args, blk) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/alki/executor.rb', line 54

def execute(meta,path,args,blk)
  type,value = nil,nil
  @semaphore.with_read_lock do
    cache_entry = @call_cache[path]
    if cache_entry
      if cache_entry == :building
        raise Alki::CircularReferenceError.new
      end
      type,value = cache_entry.type,cache_entry.value
    else
      @semaphore.with_write_lock do
        @call_cache[path] = :building
        type, value = build(path)
        @call_cache[path] = Alki::Execution::CacheEntry.finished type, value
      end
    end
  end
  call_value(type, value, meta, args, blk)
rescue Alki::CircularReferenceError => e
  e.chain << path
  raise
end

#lockObject



20
21
22
23
24
# File 'lib/alki/executor.rb', line 20

def lock
  @semaphore.with_write_lock do
    yield
  end
end

#lookup(path) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/alki/executor.rb', line 30

def lookup(path)
  @semaphore.with_read_lock do
    unless @lookup_cache[path]
      @semaphore.with_write_lock do
        @lookup_cache[path] = lookup_elem(path).tap do |elem|
          unless elem
            raise InvalidPathError.new("Invalid path #{path.inspect}")
          end
        end
      end
    end
    @lookup_cache[path]
  end
end