rider-server 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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)