rider-server 0.1.0 → 0.1.2

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.build.yml +3 -3
  3. data/CHANGELOG.md +23 -1
  4. data/COPYING +20 -0
  5. data/README.rdoc +39 -0
  6. data/Rakefile +5 -0
  7. data/exe/rider-server +3 -3
  8. data/lib/rider_server/config.rb +76 -0
  9. data/lib/rider_server/core_ext/array.rb +3 -1
  10. data/lib/rider_server/core_ext/class.rb +5 -0
  11. data/lib/rider_server/core_ext/env.rb +14 -0
  12. data/lib/rider_server/core_ext/hash.rb +3 -1
  13. data/lib/rider_server/core_ext/kernel.rb +5 -0
  14. data/lib/rider_server/core_ext/module.rb +18 -0
  15. data/lib/rider_server/core_ext/object.rb +7 -1
  16. data/lib/rider_server/core_ext/string.rb +3 -1
  17. data/lib/rider_server/core_ext/symbol.rb +3 -1
  18. data/lib/rider_server/exception_extension.rb +2 -0
  19. data/lib/rider_server/inspect.rb +115 -43
  20. data/lib/rider_server/logger.rb +11 -4
  21. data/lib/rider_server/operation.rb +39 -20
  22. data/lib/rider_server/{ops → operations}/clone.rb +3 -2
  23. data/lib/rider_server/{ops → operations}/close.rb +3 -2
  24. data/lib/rider_server/operations/completions.rb +146 -0
  25. data/lib/rider_server/operations/lookup.rb +102 -0
  26. data/lib/rider_server/operations/ls_sessions.rb +51 -0
  27. data/lib/rider_server/operations/toggle_catch_all_exceptions.rb +24 -0
  28. data/lib/rider_server/operations.rb +43 -69
  29. data/lib/rider_server/request.rb +61 -0
  30. data/lib/rider_server/response.rb +10 -2
  31. data/lib/rider_server/server.rb +29 -17
  32. data/lib/rider_server/services/capture_exceptions.rb +18 -2
  33. data/lib/rider_server/services/rails.rb +1 -1
  34. data/lib/rider_server/session.rb +77 -34
  35. data/lib/rider_server/session_operation.rb +17 -0
  36. data/lib/rider_server/session_operations/eval.rb +61 -0
  37. data/lib/rider_server/session_operations/inspect.rb +123 -0
  38. data/lib/rider_server/session_operations/inspect_exception.rb +46 -0
  39. data/lib/rider_server/session_operations/interrupt.rb +29 -0
  40. data/lib/rider_server/session_operations/load_path.rb +19 -0
  41. data/lib/rider_server/session_operations/ls_exceptions.rb +28 -0
  42. data/lib/rider_server/session_operations/ls_services.rb +18 -0
  43. data/lib/rider_server/session_operations/service.rb +42 -0
  44. data/lib/rider_server/session_operations/set_namespace.rb +82 -0
  45. data/lib/rider_server/session_operations/set_namespace_variable.rb +81 -0
  46. data/lib/rider_server/session_operations/stdin.rb +19 -0
  47. data/lib/rider_server/utils.rb +7 -7
  48. data/lib/rider_server/validate/array.rb +32 -0
  49. data/lib/rider_server/validate/base.rb +28 -0
  50. data/lib/rider_server/validate/boolean.rb +47 -0
  51. data/lib/rider_server/validate/hash.rb +32 -0
  52. data/lib/rider_server/validate/integer.rb +56 -0
  53. data/lib/rider_server/validate/predicates.rb +30 -0
  54. data/lib/rider_server/validate/string.rb +60 -0
  55. data/lib/rider_server/validate/symbol.rb +90 -0
  56. data/lib/rider_server/validate.rb +15 -0
  57. data/lib/rider_server/version.rb +1 -1
  58. data/lib/rider_server/workspace.rb +1 -1
  59. data/lib/rider_server.rb +3 -1
  60. metadata +55 -24
  61. data/README.md +0 -44
  62. data/lib/rider_server/ops/completions.rb +0 -100
  63. data/lib/rider_server/ops/eval.rb +0 -62
  64. data/lib/rider_server/ops/inspect.rb +0 -121
  65. data/lib/rider_server/ops/inspect_exception.rb +0 -47
  66. data/lib/rider_server/ops/interrupt.rb +0 -30
  67. data/lib/rider_server/ops/load_path.rb +0 -20
  68. data/lib/rider_server/ops/lookup.rb +0 -83
  69. data/lib/rider_server/ops/ls_exceptions.rb +0 -29
  70. data/lib/rider_server/ops/ls_services.rb +0 -19
  71. data/lib/rider_server/ops/ls_sessions.rb +0 -52
  72. data/lib/rider_server/ops/service.rb +0 -43
  73. data/lib/rider_server/ops/set_namespace.rb +0 -79
  74. data/lib/rider_server/ops/set_namespace_variable.rb +0 -80
  75. data/lib/rider_server/ops/stdin.rb +0 -20
  76. data/lib/rider_server/ops/toggle_catch_all_exceptions.rb +0 -27
@@ -13,38 +13,57 @@ module RiderServer
13
13
  class Operation
14
14
  include RiderServer::Logger
15
15
 
16
- attr_reader :documentation, :arguments, :controller
17
- def self.operation_name
18
- name.split("::").last.gsub(/(.)([A-Z])/, '\1_\2').downcase
16
+ # Operations registry
17
+ @operations = {}
18
+ class << self
19
+ attr_reader :operations
19
20
  end
20
21
 
21
- def self.documentation(desc)
22
- @documentation = desc
22
+ def self.handles?(request)
23
+ @operations.key? request.op
23
24
  end
24
25
 
25
- def self.argument(name, type, description, required: false)
26
- @arguments ||= []
26
+ def self.handle(context, request)
27
+ operation = @operations[request.op]
28
+ operation.validate_request!(request)
29
+ operation.handle(context, request)
30
+ end
27
31
 
28
- raise ArgumentError, "Invalid argument type #{type}" \
29
- unless [:string, :integer, :array].include?(type)
32
+ def self.define(&block)
33
+ instance = new
34
+ instance.instance_eval(&block)
35
+ raise ArgumentError, "Operation #{self} must have a name" if instance.name.empty?
36
+ raise ArgumentError, "Operation #{self} must have a documentation string" if instance.documentation.empty?
37
+ raise ArgumentError, "Operation #{self} must have at least one argument" if instance.arguments.empty?
38
+ @operations[instance.name] = instance
39
+ instance
40
+ end
30
41
 
31
- @arguments << {name: name, type: type, required: required, description: description}
42
+ attr_reader :arguments
43
+
44
+ def documentation(value = nil)
45
+ @documentation = value if value
46
+ @documentation
32
47
  end
33
48
 
34
- def initialize(controller)
35
- @controller = controller
36
- @documentation = self.class.instance_variable_get(:@documentation) || ""
37
- @arguments = self.class.instance_variable_get(:@arguments) || []
38
- raise ArgumentError, "Operation must have a documentation string" if @documentation.empty?
39
- raise ArgumentError, "Operation must have at least one argument" if @arguments.empty?
49
+ def name(value = nil)
50
+ @name = value if value
51
+ @name
40
52
  end
41
53
 
42
- def create_response(operation)
43
- Utils.create_response(operation)
54
+ def initialize
55
+ @name = ""
56
+ @arguments = []
57
+ @documentation = ""
44
58
  end
45
59
 
46
- def send_response(response)
47
- controller.send_response(response)
60
+ def argument(name, type, description, required: false)
61
+ @arguments ||= []
62
+
63
+ raise ArgumentError, "Invalid argument type #{type}" \
64
+ unless [:string, :integer, :array].include?(type)
65
+
66
+ @arguments << {name: name, type: type, required: required, description: description}
48
67
  end
49
68
 
50
69
  def validate_request!(request)
@@ -3,14 +3,15 @@ require "rider_server/response"
3
3
 
4
4
  module RiderServer
5
5
  module Ops
6
- class Clone < Operation
6
+ Operation.define do
7
+ name "clone"
7
8
  documentation "Clone a session"
8
9
 
9
10
  argument :id, :string, "The request id", required: true
10
11
  argument :session, :string, "The session to clone"
11
12
 
12
13
  # Handle the clone operation, session will be nil
13
- def handle(session, operation)
14
+ def handle(controller, operation)
14
15
  response = Response.new(operation)
15
16
 
16
17
  # Clone a specific session if specified
@@ -3,14 +3,15 @@ require "rider_server/response"
3
3
 
4
4
  module RiderServer
5
5
  module Ops
6
- class Close < Operation
6
+ Close = Operation.define do
7
+ name "close"
7
8
  documentation "Close a specific session."
8
9
 
9
10
  argument :id, :string, "The request id", required: true
10
11
  argument :session, :string, "The session to close", required: true
11
12
 
12
13
  # Handle the close operation, session will be nil
13
- def handle(session, operation)
14
+ def handle(controller, operation)
14
15
  response = Response.new(operation)
15
16
 
16
17
  session_id = operation["session"]
@@ -0,0 +1,146 @@
1
+ require "rider_server/operation"
2
+ require "rider_server/response"
3
+ require "rider_server/inspect"
4
+ require "rider_server/workspace"
5
+
6
+ module RiderServer
7
+ Operation.define do
8
+ name "completions"
9
+ documentation "Get completions for a given prefix"
10
+
11
+ argument :id, :string, "The request id", required: true
12
+ argument :prefix, :string, "The prefix to complete", required: true
13
+ argument :complete_fn, :string, "What completion function to use, top-level, module, method or singleton-method"
14
+ argument :ns, :string, "The namespace to search for completions"
15
+
16
+ @workspace = Workspace.new
17
+
18
+ def handle(controller, operation)
19
+ response = Response.new(operation)
20
+
21
+ prefix = operation["prefix"]
22
+ ns = operation["ns"]
23
+ complete_fn = operation.fetch("complete-fn", "top-level")
24
+
25
+ if prefix.nil? || parse_string(prefix).nil?
26
+ response.set("completions", [])
27
+ else
28
+ ns_object = if ns.empty?
29
+ ::Object
30
+ else
31
+ @workspace.lookup_module(ns)
32
+ end
33
+
34
+ # If the prefix isn't parseable, return an empty list
35
+ response.set("completions", lookup_module(prefix, klass: ns_object, completion_fn: complete_fn))
36
+ end
37
+ response.status("done")
38
+ response
39
+ end
40
+
41
+ def lookup_module(module_name, klass: ::Object, completion_fn: "top-level")
42
+ node = parse_string(module_name)
43
+ case node.type
44
+ when :const
45
+ ns = lookup_module_ast(node.children.first, klass)
46
+ prefix = node.children.last
47
+ all_constants(ns, prefix)
48
+ when :send
49
+ ns = lookup_module_ast(node.children.first, klass)
50
+ prefix = node.children.last
51
+ if completion_fn == "method"
52
+ all_constants(ns, prefix) + encode_methods(class_instance_methods(ns, prefix) + class_singleton_methods(::Kernel, prefix))
53
+ else
54
+ all_constants(ns, prefix) + encode_methods(class_methods(ns, prefix) + class_singleton_methods(::Kernel, prefix))
55
+ end
56
+ else
57
+ []
58
+ end
59
+ end
60
+
61
+ def parse_string(string)
62
+ buffer = Parser::Source::Buffer.new("(string)")
63
+ buffer.source = string
64
+ Parser::CurrentRuby.new.parse(buffer)
65
+ end
66
+
67
+ def lookup_module_ast(node, klass = ::Object)
68
+ return klass if node.nil?
69
+
70
+ case node.type
71
+ when :cbase
72
+ ::Object
73
+ when :const
74
+ if node.children.first.nil?
75
+ klass.const_get(node.children.last)
76
+ else
77
+ lookup_module_ast(node.children.first, klass).const_get(node.children.last)
78
+ end
79
+ else
80
+ raise ModuleLookupError, "Unknown node type #{node.type}"
81
+ end
82
+ end
83
+
84
+ def parent_constant(ns_object)
85
+ ns_object_name = ns_object.to_s
86
+ parent_name, _ = ns_object_name.rpartition("::")
87
+ parent_name.empty? ? nil : ::Object.const_get(parent_name)
88
+ end
89
+
90
+ def all_constants(ns_object, prefix)
91
+ consts = []
92
+ ns_object.constants.grep(/^#{prefix}/).each do |constant|
93
+ consts << constant.to_s
94
+ end
95
+
96
+ # Search up the tree to find all the other constants
97
+ constant = ns_object
98
+ loop do
99
+ constant = parent_constant(constant)
100
+ break if constant.nil?
101
+
102
+ constant.constants.grep(/^#{prefix}/).each do |constant|
103
+ consts << constant.to_s
104
+ end
105
+ end
106
+
107
+ ::Object.constants.grep(/^#{prefix}/).each do |constant|
108
+ consts << constant.to_s
109
+ end
110
+
111
+ consts.map do |constant|
112
+ {
113
+ "candidate" => constant,
114
+ "type" => "constant"
115
+ }
116
+ end
117
+ end
118
+
119
+ ##
120
+ # Get all instance methods that match a +prefix+ for a given object +obj+
121
+ #
122
+ # This method should be called when in the context of an
123
+ # instance method, as all other instance methods will be
124
+ # acessable.
125
+ def class_instance_methods(obj, prefix)
126
+ Set.new(obj.instance_methods.grep(/^#{prefix}/))
127
+ end
128
+
129
+ def class_methods(obj, prefix)
130
+ Set.new(obj.methods.grep(/^#{prefix}/))
131
+ end
132
+
133
+ def class_singleton_methods(obj, prefix)
134
+ Set.new(obj.singleton_methods.grep(/^#{prefix}/))
135
+ end
136
+
137
+ def encode_methods(methods)
138
+ methods.map do |method|
139
+ {
140
+ "candidate" => method.to_s,
141
+ "type" => "method"
142
+ }
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,102 @@
1
+ require "rider_server/operation"
2
+ require "rider_server/response"
3
+ require "rider_server/inspect"
4
+
5
+ module RiderServer
6
+ Operation.define do
7
+ name "lookup"
8
+ documentation "Get info about a symbol."
9
+
10
+ argument :id, :string, "The request id", required: true
11
+ argument :sym, :string, "The symbol to lookup", required: true
12
+ argument :lookup_fn, :string, "What lookup function to use, top-level, module, method or singleton-method"
13
+ argument :ns, :string, "The namespace to search for completions"
14
+
15
+ def handle(controller, operation)
16
+ response = Response.new(operation)
17
+ ns = operation["ns"]
18
+ sym = operation["sym"]
19
+ lookup_fn = operation.fetch("lookup-fn", "top-level")
20
+
21
+ if sym.nil? || parse_string(sym).nil?
22
+ response.set("info", {})
23
+ else
24
+ ns_object = if ns.empty?
25
+ ::Object
26
+ else
27
+ workspace.lookup_module(ns)
28
+ end
29
+
30
+ # If the prefix isn't parseable, return an empty list
31
+ response.set("info", lookup_module(sym, klass: ns_object, lookup_fn: lookup_fn))
32
+ end
33
+ response.status("done")
34
+ response
35
+ end
36
+
37
+ def lookup_module(module_name, klass: ::Object, lookup_fn: "top-level")
38
+ node = parse_string(module_name)
39
+ case node.type
40
+ when :const
41
+ ns = lookup_module_ast(node.children.first, klass)
42
+ name node.children.last
43
+ encode_const(ns, name)
44
+ when :send
45
+ ns = lookup_module_ast(node.children.first, klass)
46
+ prefix = node.children.last
47
+ if lookup_fn == "method"
48
+ encode_method(ns.instance_method(prefix))
49
+ else
50
+ encode_method(ns.method(prefix))
51
+ end
52
+ else
53
+ []
54
+ end
55
+ end
56
+
57
+ def parse_string(string)
58
+ buffer = Parser::Source::Buffer.new("(string)")
59
+ buffer.source = string
60
+ Parser::CurrentRuby.new.parse(buffer)
61
+ end
62
+
63
+ def lookup_module_ast(node, klass = ::Object)
64
+ return klass if node.nil?
65
+
66
+ case node.type
67
+ when :cbase
68
+ ::Object
69
+ when :const
70
+ if node.children.first.nil?
71
+ klass.const_get(node.children.last)
72
+ else
73
+ lookup_module_ast(node.children.first, klass).const_get(node.children.last)
74
+ end
75
+ else
76
+ raise ModuleLookupError, "Unknown node type #{node.type}"
77
+ end
78
+ end
79
+
80
+ def encode_const(ns, const_name)
81
+ if ns.const_defined? const_name
82
+ {
83
+ "name" => "#{ns}::#{const_name}",
84
+ "source_location" => ns.const_source_location(const_name)
85
+ }
86
+ else
87
+ {}
88
+ end
89
+ end
90
+
91
+ def encode_method(thing)
92
+ {
93
+ "name" => thing.name.to_s,
94
+ "source_location" => thing.source_location
95
+ }
96
+ end
97
+
98
+ def workspace
99
+ @workspace ||= Workspace.new
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,51 @@
1
+ require "rider_server/operation"
2
+ require "rider_server/response"
3
+
4
+ module RiderServer
5
+ Operation.define do
6
+ name "ls-sessions"
7
+ documentation "List all sessions"
8
+
9
+ argument :id, :string, "The request id", required: true
10
+
11
+ def handle(controller, operation)
12
+ response = Response.new(operation)
13
+ response.set("sessions", controller.sessions.map { |k, v| k })
14
+ response.set("rider/session-headings",
15
+ [
16
+ {
17
+ "id" => "id",
18
+ "name" => "ID",
19
+ "length" => 36
20
+ },
21
+ {
22
+ "id" => "namespace_name",
23
+ "name" => "Namespace",
24
+ "length" => 25
25
+ },
26
+ {
27
+ "id" => "history_items",
28
+ "name" => "History Items",
29
+ "length" => 5
30
+ },
31
+ {
32
+ "id" => "exceptions",
33
+ "name" => "Exceptions",
34
+ "length" => 5
35
+ }
36
+ ])
37
+ response.set("rider/sessions", controller.sessions.map { |k, v| session_summary(v) })
38
+ response.status("done")
39
+ response
40
+ end
41
+
42
+ def session_summary(session)
43
+ {
44
+ "id" => session.id,
45
+ "namespace_name" => session.workspace.namespace_name,
46
+ "history_items" => session.history.length.to_s,
47
+ "exceptions" => session.exceptions.length.to_s
48
+ }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ require "rider_server/operation"
2
+ require "rider_server/response"
3
+
4
+ module RiderServer
5
+ Operation.define do
6
+ name "toggle-catch-all-exceptions"
7
+ documentation "Enable catching all exceptions. Not just the ones with a session."
8
+
9
+ argument :id, :string, "The request id", required: true
10
+
11
+ def handle(controller, operation)
12
+ value = if controller.toggle_capture_exceptions
13
+ "enabled"
14
+ else
15
+ "disabled"
16
+ end
17
+
18
+ response = Response.new(operation)
19
+ response.status("done")
20
+ response.set("value", value)
21
+ response
22
+ end
23
+ end
24
+ end
@@ -12,112 +12,78 @@ require "rider_server/session"
12
12
  require "rider_server/errors"
13
13
  require "rider_server/response"
14
14
  require "rider_server/core_ext/array"
15
+ require "rider_server/core_ext/class"
16
+ require "rider_server/core_ext/env"
15
17
  require "rider_server/core_ext/hash"
18
+ require "rider_server/core_ext/kernel"
19
+ require "rider_server/core_ext/module"
16
20
  require "rider_server/core_ext/object"
17
21
  require "rider_server/core_ext/string"
18
22
  require "rider_server/core_ext/symbol"
19
- require "rider_server/ops/clone"
20
- require "rider_server/ops/close"
21
- require "rider_server/ops/completions"
22
- require "rider_server/ops/eval"
23
- require "rider_server/ops/inspect"
24
- require "rider_server/ops/inspect_exception"
25
- require "rider_server/ops/interrupt"
26
- require "rider_server/ops/load_path"
27
- require "rider_server/ops/lookup"
28
- require "rider_server/ops/ls_exceptions"
29
- require "rider_server/ops/ls_services"
30
- require "rider_server/ops/ls_sessions"
31
- require "rider_server/ops/service"
32
- require "rider_server/ops/set_namespace"
33
- require "rider_server/ops/set_namespace_variable"
34
- require "rider_server/ops/toggle_catch_all_exceptions"
23
+ require "rider_server/operations/clone"
24
+ require "rider_server/operations/close"
25
+ require "rider_server/operations/completions"
26
+ require "rider_server/operations/lookup"
27
+ require "rider_server/operations/ls_sessions"
28
+ require "rider_server/operations/toggle_catch_all_exceptions"
35
29
 
36
30
  module RiderServer
31
+ def self.create_operation_handler(config, response_queue)
32
+ Operations.new(config, response_queue)
33
+ end
34
+
37
35
  class Operations
38
36
  include RiderServer::Logger
39
37
 
40
- attr_reader :executing_requests
41
38
  attr_reader :sessions
42
- attr_reader :stdin, :stdout, :stderr
43
39
  attr_reader :response_queue
44
- attr_accessor :sessions_catching_exceptions
45
-
46
- OPERATIONS = [
47
- Ops::Clone,
48
- Ops::Close,
49
- Ops::Completions,
50
- Ops::Eval,
51
- Ops::Inspect,
52
- Ops::InspectException,
53
- Ops::Interrupt,
54
- Ops::LoadPath,
55
- Ops::Lookup,
56
- Ops::LsExceptions,
57
- Ops::LsServices,
58
- Ops::LsSessions,
59
- Ops::Service,
60
- Ops::SetNamespace,
61
- Ops::SetNamespaceVariable,
62
- Ops::ToggleCatchAllExceptions
63
- ]
64
40
 
65
- def initialize(response_queue)
41
+ def initialize(config, response_queue)
42
+ @config = config
66
43
  @sessions = {}
67
44
  @response_queue = response_queue
68
- @executing_requests = []
69
- @operations = OPERATIONS.each_with_object({}) do |klass, h|
70
- h[klass.operation_name] = klass.new(self)
71
- end
72
- @sessions_catching_exceptions = []
73
45
  end
74
46
 
75
47
  def send_response(response)
76
48
  if response
77
49
  @response_queue.push(response)
78
- if response.done?
79
- @executing_requests.delete(response.id)
80
- end
81
50
  end
82
51
  end
83
52
 
84
- def handle(operation)
85
- session = nil
86
-
87
- session_id = operation["session"]
88
- op = operation["op"].tr("-", "_")
89
- log.info("Handling operation '#{operation}'")
90
- session = get_session(session_id)
91
- @executing_requests << operation["id"]
92
- if @operations.key? op
93
- @operations[op].validate_request!(operation)
94
- send_response(@operations[op].handle(session, operation))
53
+ def handle(request)
54
+ op = request.op
55
+ log.info("Handling operation '#{request.inspect}'")
56
+ session = get_session(request.session)
57
+ if Operation.handles?(request)
58
+ send_response(Operation.handle(self, request))
59
+ elsif !session.nil? && SessionOperation.handles?(request)
60
+ send_response(SessionOperation.handle(session, request))
95
61
  else
96
62
  log.warn("Unknown operation '#{op}' requested")
97
- response = Response.new(operation)
63
+ response = Response.new(request)
98
64
  response.status "unknown-op", "done"
99
65
  send_response(response)
100
66
  end
101
67
  rescue ScriptError, StandardError => e
102
- response = Response.new(operation)
68
+ response = Response.new(request)
103
69
  response.set("ex", e.inspect)
104
70
  response.set("out", e.full_message)
105
71
  response.status("eval-error", "done")
72
+ log.error "Error handling request: #{e}\n #{e.backtrace.join("\n")}"
106
73
  if session
107
- exception_id = session.add_exception(operation["id"], e)
108
- response.set("rider/exception-id", exception_id)
109
- end
110
-
111
- # Broadcast the exception to sessions that are listening
112
- @sessions_catching_exceptions.each do |s|
113
- next if session == s
114
- @sessions[s]&.add_exception(operation["id"], e)
74
+ exception = session.add_exception(request.id, e)
75
+ response.set("rider/exception-id", exception["id"])
115
76
  end
77
+ RiderServer::Services::CaptureExceptions.handle_exception(e)
116
78
  send_response(response)
117
79
  end
118
80
 
81
+ #
82
+ # Sessions
83
+ #
84
+
119
85
  def new_session
120
- Session.new(@response_queue)
86
+ RiderServer.create_session(@config, @response_queue)
121
87
  end
122
88
 
123
89
  def get_session(id)
@@ -132,5 +98,13 @@ module RiderServer
132
98
  def delete_session(session_id)
133
99
  @sessions.delete(session_id)
134
100
  end
101
+
102
+ #
103
+ # Exceptions
104
+ #
105
+
106
+ def toggle_capture_exceptions
107
+ @config.capture_exceptions(!@config.capture_exceptions)
108
+ end
135
109
  end
136
110
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # request.rb -- A simple wrapper around a request
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ require "bencode"
11
+
12
+ module RiderServer
13
+ class Request
14
+ def initialize(operation)
15
+ raise "Operation ID cannot be nil" if operation["id"].nil?
16
+ raise "Operation name cannot be nil" if operation["op"].nil?
17
+
18
+ @data = operation
19
+ end
20
+
21
+ def op
22
+ @data["op"]
23
+ end
24
+
25
+ def id
26
+ @data["id"]
27
+ end
28
+
29
+ def session
30
+ @data["session"]
31
+ end
32
+
33
+ def set(key, value)
34
+ @data[key] = value
35
+ end
36
+
37
+ def fetch(*args)
38
+ @data.fetch(*args)
39
+ end
40
+
41
+ def key?(name)
42
+ @data.key? name
43
+ end
44
+
45
+ def [](name)
46
+ @data[name]
47
+ end
48
+
49
+ def []=(name, value)
50
+ @data[name] = value
51
+ end
52
+
53
+ def inspect
54
+ "#<RiderServer::Request:#{object_id} id=#{id} session=#{session} op=#{op}}>"
55
+ end
56
+
57
+ def to_h
58
+ @data
59
+ end
60
+ end
61
+ end
@@ -42,8 +42,16 @@ module RiderServer
42
42
  @data.fetch(*args)
43
43
  end
44
44
 
45
- def [](item)
46
- @data[item]
45
+ def key?(name)
46
+ @data.key? name
47
+ end
48
+
49
+ def [](name)
50
+ @data[name]
51
+ end
52
+
53
+ def []=(name, value)
54
+ @data[name] = value
47
55
  end
48
56
 
49
57
  def status(*value)