delfos 0.0.2.pre.rc2 → 0.0.2.pre.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/exe/delfos_import +38 -0
  3. data/exe/delfos_import_offline_queries +9 -0
  4. data/exe/delfos_update_distance +11 -0
  5. data/lib/delfos.rb +29 -73
  6. data/lib/delfos/config.rb +90 -0
  7. data/lib/delfos/config/inclusion.rb +90 -0
  8. data/lib/delfos/file_system.rb +7 -2
  9. data/lib/delfos/file_system/app_directories.rb +16 -18
  10. data/lib/delfos/file_system/app_files.rb +31 -0
  11. data/lib/delfos/file_system/file_cache.rb +21 -0
  12. data/lib/delfos/file_system/path_determination.rb +10 -7
  13. data/lib/delfos/method_trace.rb +18 -6
  14. data/lib/delfos/method_trace/call_handler.rb +6 -2
  15. data/lib/delfos/method_trace/code_location.rb +2 -12
  16. data/lib/delfos/method_trace/code_location/container_method_factory.rb +50 -25
  17. data/lib/delfos/method_trace/code_location/eval_in_caller.rb +2 -4
  18. data/lib/delfos/method_trace/code_location/filename_helpers.rb +1 -1
  19. data/lib/delfos/method_trace/code_location/method.rb +13 -9
  20. data/lib/delfos/neo4j.rb +12 -3
  21. data/lib/delfos/neo4j/distance/update.rb +1 -1
  22. data/lib/delfos/neo4j/live/call_site_logger.rb +27 -0
  23. data/lib/delfos/neo4j/offline.rb +13 -0
  24. data/lib/delfos/neo4j/offline/call_site_logger.rb +6 -1
  25. data/lib/delfos/neo4j/offline/importer.rb +8 -7
  26. data/lib/delfos/neo4j/query_execution/batch/execution.rb +93 -0
  27. data/lib/delfos/neo4j/query_execution/batch/retryable.rb +103 -0
  28. data/lib/delfos/neo4j/query_execution/errors.rb +4 -3
  29. data/lib/delfos/neo4j/query_execution/http.rb +1 -1
  30. data/lib/delfos/neo4j/query_execution/sync.rb +1 -1
  31. data/lib/delfos/neo4j/query_execution/transactional.rb +1 -1
  32. data/lib/delfos/neo4j/schema.rb +1 -1
  33. metadata +38 -16
  34. data/lib/delfos/neo4j/batch/execution.rb +0 -91
  35. data/lib/delfos/neo4j/batch/retryable.rb +0 -101
  36. data/lib/delfos/setup.rb +0 -120
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "file_cache"
4
+
5
+ module Delfos
6
+ module FileSystem
7
+ class AppFiles
8
+ include FileCache
9
+
10
+ def initialize(included, excluded)
11
+ @included = included
12
+ @excluded = excluded
13
+ end
14
+
15
+ def include?(file)
16
+ !exclude?(file)
17
+ end
18
+
19
+ def exclude?(file)
20
+ return false if file.nil?
21
+ with_cache(file) { should_exclude?(file) }
22
+ end
23
+
24
+ private
25
+
26
+ def should_exclude?(file)
27
+ @excluded.include?(Pathname(file).expand_path)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Delfos
4
+ module FileSystem
5
+ module FileCache
6
+ def reset!
7
+ @cache = nil
8
+ end
9
+
10
+ private
11
+
12
+ def with_cache(key)
13
+ cache.include?(key) ? cache[key] : cache[key] = yield
14
+ end
15
+
16
+ def cache
17
+ @cache ||= {}
18
+ end
19
+ end
20
+ end
21
+ end
@@ -15,18 +15,21 @@ module Delfos
15
15
 
16
16
  def full_path
17
17
  return @file.realpath if Pathname.new(@file).exist?
18
-
19
- Delfos.application_directories.map do |d|
20
- path = try_path { d + @file }
21
-
22
- path || try_path do
23
- Pathname.new(d + @file.to_s.gsub(%r{[^/]*/}, ""))
24
- end
18
+ Delfos.config.included_directories.map do |d|
19
+ determine_path(d)
25
20
  end.compact.first
26
21
  end
27
22
 
28
23
  private
29
24
 
25
+ def determine_path(d)
26
+ path = try_path { d + @file }
27
+
28
+ path || try_path do
29
+ Pathname.new(d + @file.to_s.gsub(%r{[^/]*/}, ""))
30
+ end
31
+ end
32
+
30
33
  def strip_block_message(f)
31
34
  f.to_s.split(" in block").first
32
35
  end
@@ -6,7 +6,24 @@ require_relative "call_stack"
6
6
  module Delfos
7
7
  module MethodTrace
8
8
  class << self
9
- def trace!
9
+ def enable!
10
+ method_trace.perform
11
+ end
12
+
13
+ def disable!
14
+ @method_trace&.disable!
15
+ @method_trace = nil
16
+ end
17
+
18
+ private
19
+
20
+ def method_trace
21
+ @method_trace ||= Setup.new
22
+ end
23
+ end
24
+
25
+ class Setup
26
+ def perform
10
27
  on_call.enable
11
28
  on_return.enable
12
29
  @last_returned = nil
@@ -14,12 +31,7 @@ module Delfos
14
31
 
15
32
  def disable!
16
33
  @on_call&.disable
17
- @on_call = nil
18
-
19
34
  @on_return&.disable
20
- @on_return = nil
21
-
22
- @last_returned = nil
23
35
  end
24
36
 
25
37
  def on_call
@@ -2,14 +2,14 @@
2
2
 
3
3
  require "delfos/call_stack"
4
4
  require_relative "code_location"
5
- require_relative "code_location/filename_helpers"
5
+ require_relative "code_location/eval_in_caller"
6
6
 
7
7
  module Delfos
8
8
  module MethodTrace
9
9
  CallHandler = Struct.new(:trace_point)
10
10
 
11
11
  class CallHandler
12
- include CodeLocation::FilenameHelpers
12
+ include CodeLocation::EvalInCaller
13
13
 
14
14
  def perform
15
15
  return unless relevant?
@@ -17,8 +17,12 @@ module Delfos
17
17
  CallStack.push(call_site)
18
18
  end
19
19
 
20
+ STACK_OFFSET = 7
21
+
20
22
  def call_site
21
23
  @call_site ||= CodeLocation.callsite_from(
24
+ file: eval_in_caller("__FILE__", STACK_OFFSET),
25
+ line_number: eval_in_caller("__LINE__", STACK_OFFSET),
22
26
  container_method: container_method,
23
27
  called_method: called_method,
24
28
  )
@@ -3,27 +3,17 @@
3
3
  require_relative "code_location/method"
4
4
  require_relative "code_location/call_site"
5
5
  require_relative "code_location/container_method_factory"
6
- require_relative "code_location/eval_in_caller"
7
6
 
8
7
  module Delfos
9
8
  module MethodTrace
10
9
  module CodeLocation
11
10
  class << self
12
- include EvalInCaller
13
-
14
11
  def method_from(attrs)
15
12
  Method.new(attrs)
16
13
  end
17
14
 
18
- STACK_OFFSET = 8
19
-
20
- def callsite_from(container_method:, called_method:, stack_offset: STACK_OFFSET)
21
- CallSite.new(
22
- container_method: container_method,
23
- called_method: called_method,
24
- file: eval_in_caller("__FILE__", stack_offset),
25
- line_number: eval_in_caller("__LINE__", stack_offset),
26
- )
15
+ def callsite_from(attrs)
16
+ CallSite.new(attrs)
27
17
  end
28
18
 
29
19
  def create_container_method
@@ -9,7 +9,9 @@ module Delfos
9
9
  class ContainerMethodFactory
10
10
  include EvalInCaller
11
11
  include FilenameHelpers
12
+
12
13
  STACK_OFFSET = 12
14
+
13
15
  attr_reader :stack_offset
14
16
 
15
17
  def self.create(stack_offset: STACK_OFFSET)
@@ -21,49 +23,72 @@ module Delfos
21
23
  end
22
24
 
23
25
  def create
24
- # ensure evaluated and memoised with correct stack offset
25
- class_method
26
-
27
- CodeLocation.method_from(
28
- object: object,
29
- method_name: meth,
30
- file: file,
31
- line_number: line,
32
- class_method: class_method,
33
- )
26
+ # ensure memoised with correct stack offset
27
+ method_object
28
+ source_location
29
+
30
+ CodeLocation.method_from(attrs)
34
31
  end
35
32
 
36
33
  private
37
34
 
38
- def object
39
- @object ||= eval_in_caller("self", stack_offset)
35
+ def attrs
36
+ {
37
+ object: object,
38
+ method_name: method_name,
39
+ file: file,
40
+ line_number: line,
41
+ class_method: class_method,
42
+ method_object: method_object,
43
+ super_method: super_method,
44
+ }
40
45
  end
41
46
 
42
47
  def class_method
43
48
  return @class_method if defined?(@class_method)
44
49
 
45
- @class_method = eval_in_caller("is_a?(Module)", STACK_OFFSET)
50
+ @class_method = object.is_a?(Module)
46
51
  end
47
52
 
48
- RUBY_IS_MAIN = "self.class == Object && self&.to_s == 'main' && __method__.nil?"
49
- RUBY_SOURCE_LOCATION = "(__method__).source_location if __method__"
50
- RUBY_CLASS_METHOD_SOURCE = "method#{RUBY_SOURCE_LOCATION}"
51
- RUBY_INSTANCE_METHOD_SOURCE = "self.class.instance_method#{RUBY_SOURCE_LOCATION}"
53
+ def file
54
+ return @file if defined? @file
52
55
 
53
- def method_finder
54
- @method_finder ||= class_method ? RUBY_CLASS_METHOD_SOURCE : RUBY_INSTANCE_METHOD_SOURCE
56
+ @file = source_location&.first
55
57
  end
56
58
 
57
- def file
58
- @file ||= eval_in_caller("(#{RUBY_IS_MAIN}) ? __FILE__ : ((#{method_finder})&.first)", stack_offset)
59
+ def line
60
+ return @line if defined? @line
61
+
62
+ @line = source_location&.last
59
63
  end
60
64
 
61
- def line
62
- @line ||= eval_in_caller("(#{RUBY_IS_MAIN}) ? __LINE__ : ((#{method_finder})&.last)", stack_offset)
65
+ def source_location
66
+ return @source_location if defined? @source_location
67
+
68
+ @source_location =
69
+ method_object&.source_location ||
70
+ eval_in_caller("[__FILE__, __LINE__]", stack_offset)
63
71
  end
64
72
 
65
- def meth
66
- @meth ||= eval_in_caller("__method__", stack_offset)
73
+ REPRESENTATION_OF_MAIN = Object.new
74
+
75
+ def object
76
+ @object ||= method_object&.receiver || REPRESENTATION_OF_MAIN
77
+ end
78
+
79
+ def method_name
80
+ @method_name ||= method_object&.name
81
+ end
82
+
83
+ def super_method
84
+ method_object&.super_method
85
+ end
86
+
87
+ RUBY_METHOD = "method(__method__) if __method__"
88
+
89
+ def method_object
90
+ return @method_object if defined? @method_object
91
+ @method_object = eval_in_caller(RUBY_METHOD, stack_offset)
67
92
  end
68
93
  end
69
94
  end
@@ -6,10 +6,8 @@ module Delfos
6
6
  module MethodTrace
7
7
  module CodeLocation
8
8
  module EvalInCaller
9
- def eval_in_caller(s, offset, &block)
10
- other = binding.of_caller(offset)
11
-
12
- other.eval(s)
9
+ def eval_in_caller(s, offset)
10
+ binding.of_caller(offset).eval(s)
13
11
  end
14
12
  end
15
13
  end
@@ -22,7 +22,7 @@ module Delfos
22
22
  return unless f
23
23
  file = f.to_s
24
24
 
25
- Delfos.application_directories.map do |d|
25
+ Delfos.config.included_directories.map do |d|
26
26
  file = relative_path(file, d)
27
27
  end
28
28
 
@@ -7,15 +7,19 @@ module Delfos
7
7
  module CodeLocation
8
8
  class Method
9
9
  include FilenameHelpers
10
- attr_reader :object, :line_number, :class_method
11
-
12
- def initialize(object:, method_name:, file:, line_number:, class_method:)
13
- @object = object
14
- @method_name = method_name
15
- @file = file
16
- @line_number = line_number
17
- @class_method = class_method
18
- end
10
+ attr_reader :object, :line_number, :class_method, :method_object, :super_method
11
+
12
+ # rubocop:disable Metrics/ParameterLists
13
+ def initialize(object:, method_name:, file:, line_number:, class_method:, method_object: nil, super_method: nil)
14
+ @object = object
15
+ @method_name = method_name
16
+ @file = file
17
+ @line_number = line_number
18
+ @class_method = class_method
19
+ @method_object = method_object
20
+ @super_method = super_method
21
+ end
22
+ # rubocop:enable Metrics/ParameterLists
19
23
 
20
24
  def klass_name
21
25
  klass.name
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "neo4j/query_execution/sync"
4
- require_relative "neo4j/batch/retryable"
4
+ require_relative "neo4j/query_execution/batch/retryable"
5
5
  require_relative "neo4j/schema"
6
6
  require_relative "neo4j/distance/update"
7
+ require_relative "neo4j/offline"
7
8
 
8
9
  module Delfos
9
10
  module Neo4j
@@ -14,11 +15,15 @@ module Delfos
14
15
  end
15
16
 
16
17
  def execute(query, params = {})
17
- Batch::Retryable.execute!(query, params: params, size: Delfos.batch_size)
18
+ QueryExecution::Batch::Retryable.execute!(query, params: params, size: Delfos.batch_size)
18
19
  end
19
20
 
20
21
  def flush!
21
- Batch::Retryable.flush!
22
+ QueryExecution::Batch::Retryable.flush!
23
+ end
24
+
25
+ def reset!
26
+ Delfos::Neo4j::QueryExecution::Batch::Retryable.reset!
22
27
  end
23
28
 
24
29
  def ensure_schema!
@@ -28,6 +33,10 @@ module Delfos
28
33
  )
29
34
  end
30
35
 
36
+ def import_offline_queries(filename)
37
+ Offline.import_queries(filename)
38
+ end
39
+
31
40
  def update_distance!
32
41
  Distance::Update.new.perform
33
42
  end
@@ -9,7 +9,7 @@ module Delfos
9
9
  class Update
10
10
  def perform
11
11
  results = CallSiteFetcher.perform
12
- return if results.length.negative?
12
+ return unless results.length.positive?
13
13
 
14
14
  results.each do |start_file, call_site_id, finish_file, called_id|
15
15
  handle(start_file, call_site_id, finish_file, called_id)
@@ -11,6 +11,33 @@ module Delfos
11
11
 
12
12
  Neo4j.execute(q.query, q.params)
13
13
  end
14
+
15
+ def finish!
16
+ reset_call_stack!
17
+ update_distance!
18
+ end
19
+
20
+ def reset!
21
+ reset_call_stack!
22
+ Neo4j.reset!
23
+ end
24
+
25
+ private
26
+
27
+ def flush!
28
+ Neo4j.flush!
29
+ end
30
+
31
+ def update_distance!
32
+ Neo4j.update_distance!
33
+ flush!
34
+ end
35
+
36
+ def reset_call_stack!
37
+ Delfos::CallStack.pop_until_top!
38
+ Delfos::CallStack.reset!
39
+ flush!
40
+ end
14
41
  end
15
42
  end
16
43
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "offline/importer"
4
+
5
+ module Delfos
6
+ module Neo4j
7
+ module Offline
8
+ def self.import_queries(filename)
9
+ Importer.new(filename).perform
10
+ end
11
+ end
12
+ end
13
+ end
@@ -17,11 +17,16 @@ module Delfos
17
17
  file.flush if (count % 100).zero?
18
18
  end
19
19
 
20
+ def reset!
21
+ finish!
22
+ end
23
+
20
24
  def finish!
21
- return if file.closed?
25
+ return if Delfos.offline_query_filename.nil? || file.closed?
22
26
 
23
27
  file.flush
24
28
  file.close
29
+ @file = nil
25
30
  end
26
31
 
27
32
  def count