qwe 0.0.1 → 0.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47af0803616e55171f1a450977dd4b72b1b94d8175b89609902a504b5289b1e3
4
- data.tar.gz: 74c203d62db281e90db12badbe71f61bc01e3048b8d823005e035adb61658084
3
+ metadata.gz: 9163afb748f542c3cee0749fa5cb182100c2c46c5eb52c7834dd6a9e9928e569
4
+ data.tar.gz: f36a49f10487cae9d6c6caeb5774946355d072e832d4139f6e3f74af8b65b8dc
5
5
  SHA512:
6
- metadata.gz: 793f496b7be56bd4c51f0954a9a9755d079cf4d76be1bf4f9fba2de584abfd3c5fdaf32297652a95c5ce96eb3fd0686743e583bcec56989e42adbf903cfd9165
7
- data.tar.gz: efb62e30e52a37ddaf36d0de164ab65be87e307115ac5325ad1ff6131e35ef31f3257512a4d57ce41ebe9675721e78fe4b9ef13a543651a2b5bb36c355b77f8b
6
+ metadata.gz: c11193ca71612d9433848ec7217da3d9b795be3f73b70fc1f0ce6a01254bd908d3a6472c33aff7d1d8f7e72b30ad91492b7be02261d02bac1a3c2391369ae6d1
7
+ data.tar.gz: e2147f520f70ec10510236d22e62a48b28eb5b1bb63b9db759d0dce62a8d491e63e90c0d452e83d5aca9251ef8fe0f63c3679f4ce682eea074600d2f3e34e665
data/DOCS.md CHANGED
@@ -5,7 +5,7 @@
5
5
  Gem provides `qwe` executable, which starts the server by default. See `qwe -h` for details.
6
6
 
7
7
  `-r` parameter is required for entrypoint to load your classes.
8
- Int rails it's reasonable to have `config/qwe.rb` for that purpose:
8
+ In rails it's reasonable to have `config/qwe.rb` for that purpose:
9
9
  ```ruby
10
10
  APP_PATH = File.realpath("../")
11
11
 
data/Gemfile.lock CHANGED
@@ -1,14 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qwe (0.0.0)
4
+ qwe (0.0.1)
5
5
  drb (~> 2.2.1)
6
- ruby-zstds (~> 1.3)
6
+ zstd-ruby (~> 1.5)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- adsp (1.0.10)
12
11
  ast (2.4.2)
13
12
  cgi (0.4.1)
14
13
  drb (2.2.1)
@@ -51,8 +50,6 @@ GEM
51
50
  rubocop (>= 1.48.1, < 2.0)
52
51
  rubocop-ast (>= 1.30.0, < 2.0)
53
52
  ruby-progressbar (1.13.0)
54
- ruby-zstds (1.3.1)
55
- adsp (~> 1.0)
56
53
  standard (1.35.1)
57
54
  language_server-protocol (~> 3.17.0.2)
58
55
  lint_roller (~> 1.0)
@@ -68,6 +65,7 @@ GEM
68
65
  standardrb (1.0.1)
69
66
  standard
70
67
  unicode-display_width (2.5.0)
68
+ zstd-ruby (1.5.6.6)
71
69
 
72
70
  PLATFORMS
73
71
  x86_64-linux
data/README.md CHANGED
@@ -1,11 +1,21 @@
1
1
  # Qwe - pure ruby framework for stuff
2
2
 
3
- The stuff is mostly complex ruby objects living in RAM for a long time, accessed over DRb. Qwe provides database-like interface for managing that with a few extras, while attempting to impose as little bounds
4
- as possible on the way you write code.
3
+ It might be useful if you have:
4
+ - Extra high loads
5
+ - Extensive interaction
6
+ - Complexity in fitting into database
7
+
8
+ Qwe is built upon [DRb](https://docs.ruby-lang.org/en/3.3/DRb.html), which provides a way to directly access ruby objects from different processes, thus avoiding latency, JSON or XML conversions, and disk I/O limits.
9
+
10
+ Qwe manages:
11
+ - Serving and accessing objects over DRb
12
+ - Persisting them on disk
13
+ - Loading them back into RAM upon access
14
+ - Tracing every change
5
15
 
6
16
  [Full Documentation](DOCS.md)
7
17
 
8
- [Multiplayer paint example](https://gitlab.com/goose3228/qwe-paint)
18
+ [Multiplayer paint example](https://gitlab.com/goose3228/qwe-paint) - Qwe is fast enough to process mouse events on server side.
9
19
 
10
20
  ## Installation
11
21
 
@@ -32,7 +42,7 @@ The hash is now accessible from any ruby process with `Qwe::DB[]`,
32
42
  considering you know that id.
33
43
 
34
44
  ```ruby
35
- Qwe::DB[id][:qwe] = 123
45
+ Qwe::DB[id][:one_two_three] = 123
36
46
  ```
37
47
 
38
48
  After a period of inactivity, or manually if configured,
@@ -135,6 +145,8 @@ by running independent Qwe servers.
135
145
  DRb does not provide any access control, and opens separate port for each object it serves.
136
146
  It is safe to run Qwe in docker container or other isolated network, and unsafe to run on virtual or physical device with all ports open.
137
147
 
148
+ In web applications Qwe may be accessed though websockets without providing direct access to ruby methods.
149
+
138
150
  See [DRb docs](https://docs.ruby-lang.org/en/3.3/DRb.html#module-DRb-label-Security) for a more detailed explanation.
139
151
 
140
152
  ## License
data/exe/qwe CHANGED
@@ -39,7 +39,7 @@ opt_parser = OptionParser.new do |parser|
39
39
  args[:threads] = a.to_i
40
40
  end
41
41
 
42
- parser.on("--gc=SECONDS", "--gc_interval=SECONDS", "Call garbage collector (GC.start) every x seconds. Off by default") do |a|
42
+ parser.on("--gc=SECONDS", "--gc_interval=SECONDS", "Call garbage collector (GC.start) every x seconds. Off by default. Ruby can ignore garbage collection at 100% CPU load, and --gc forces ruby to still do that.") do |a|
43
43
  args[:gc_interval] = a.to_i
44
44
  end
45
45
 
@@ -86,30 +86,8 @@ if args[:watch]
86
86
  end
87
87
  sleep
88
88
  elsif args[:interactive]
89
- require "irb"
90
-
91
- Qwe::DB.connect("druby://localhost:#{args[:port]}") if args[:port]
92
-
93
- if args[:interactive] > 0
94
- obj = Qwe::DB[args[:interactive]]
95
- puts "\e[0;32mQwe interactive prompt\e[0m, record \e[1;32m##{args[:interactive]}\e[0m, class \e[1;36m#{obj.record.obj_eval("self.class.to_s")}\e[0m"
96
- else
97
- obj = Qwe::DB.server.pick_worker
98
- puts "\e[0;32mQwe interactive prompt\e[0m, worker \e[1;36m#{obj.uri}\e[0m, require #{obj.requirements}"
99
-
100
- require obj.requirements
101
- end
102
-
103
- (obj.instance_exec { binding }).instance_exec do
104
- irb(show_code: false)
105
- rescue
106
- # Older irb versions always print source code around call point
107
- IRB.setup(source_location[0], argv: [])
108
- workspace = IRB::WorkSpace.new(self)
109
- binding_irb = IRB::Irb.new(workspace)
110
- binding_irb.context.irb_path = File.expand_path(source_location[0])
111
- binding_irb.run(IRB.conf)
112
- end
89
+ require_relative "../lib/qwe/console"
90
+ Qwe::Console.start(args[:interactive], args[:port])
113
91
  elsif args[:create]
114
92
  Qwe::DB.connect("druby://localhost:#{args[:port]}") if args[:port]
115
93
  puts Qwe::DB.create(args[:create].to_sym)
data/lib/qwe/attribute.rb CHANGED
@@ -116,7 +116,7 @@ module Qwe
116
116
  end
117
117
 
118
118
  add(:default) do
119
- reader.stage "self.#{name} = " + init_or_default_stage(:default) + " unless @#{name}"
119
+ reader.stage "self.#{name} = " + init_or_default_stage(:default) + " if @#{name}.nil?"
120
120
  end
121
121
 
122
122
  add(:convert) do
@@ -0,0 +1,66 @@
1
+ require "irb"
2
+
3
+ module Qwe
4
+ class Console
5
+ def self.start(...)
6
+ new(...).start
7
+ end
8
+
9
+ attr_reader :id, :port
10
+
11
+ def initialize(id = 0, port = nil)
12
+ @id = id.to_i
13
+ @port = if port
14
+ port.to_i
15
+ else
16
+ Qwe::DB::Server::DEFAULT_PORT
17
+ end
18
+
19
+ Qwe::DB.connect("druby://localhost:#{port}") if port
20
+ setup
21
+ end
22
+
23
+ def setup
24
+ if id > 0
25
+ IRB::WorkSpace.define_method(:evaluate, &record_proc)
26
+ req = Qwe::DB[id].record.evaluate("Worker.instance.requirements")
27
+ msg = "\e[1;35mQwe interactive prompt\e[0m, record \e[1;32m##{id}\e[0m"
28
+ else
29
+ IRB::WorkSpace.define_method(:evaluate, &worker_proc)
30
+ req = Qwe::DB.server.pick_worker.requirements
31
+ msg = "\e[1;35mQwe interactive prompt\e[0m, random worker"
32
+ end
33
+
34
+ puts msg
35
+ require req if req
36
+ end
37
+
38
+ def to_s
39
+ "Qwe id=#{id}"
40
+ end
41
+
42
+ def start
43
+ binding.irb(show_code: false)
44
+ rescue
45
+ # Older irb versions always print source code around call point
46
+ IRB.setup(source_location[0], argv: [])
47
+ workspace = IRB::WorkSpace.new(self)
48
+ binding_irb = IRB::Irb.new(workspace)
49
+ binding_irb.context.irb_path = File.expand_path(source_location[0])
50
+ binding_irb.run(IRB.conf)
51
+ end
52
+
53
+ def record_proc
54
+ i = id
55
+ proc do |statements, *args|
56
+ Qwe::DB[i].record.evaluate(statements)
57
+ end
58
+ end
59
+
60
+ def worker_proc
61
+ proc do |statements, *args|
62
+ Qwe::DB.server.pick_worker.evaluate(statements)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "zstds"
3
+ require "zstd-ruby"
4
4
  require "fileutils"
5
5
 
6
6
  module Qwe::DB
@@ -12,17 +12,23 @@ module Qwe::DB
12
12
  def initialize(dir)
13
13
  @path = File.join(dir, "commits")
14
14
  @archive_path = File.join(dir, "commits.zst")
15
- unless File.exist?(@archive_path)
16
- @file = File.open(@path, "a+")
17
- end
15
+ open
16
+ end
17
+
18
+ def open
19
+ return if @file && !@file.closed? || File.exist?(@archive_path)
20
+ @file = File.open(@path, "a+")
18
21
  end
19
22
 
20
23
  def write(str)
21
- unless file
24
+ if !file
22
25
  log "Write #{str} to archived commits file #{path}, unpacking"
23
- ZSTDS::File.decompress archive_path, path
24
- FileUtils.rm_f(archive_path)
26
+ data = read_archive
25
27
  @file = File.open(@path, "a+")
28
+ @file.write(data)
29
+ FileUtils.rm_f(archive_path)
30
+ elsif file.closed?
31
+ open
26
32
  end
27
33
  file.write(str)
28
34
  rescue => e
@@ -31,7 +37,7 @@ module Qwe::DB
31
37
  end
32
38
 
33
39
  def read(line = nil)
34
- if file
40
+ if file && !file.closed?
35
41
  file.flush
36
42
  file.rewind
37
43
  if line
@@ -41,10 +47,12 @@ module Qwe::DB
41
47
  file.read
42
48
  end
43
49
  else
44
- cs = ZSTDS::Stream::Reader.open(archive_path) do |r|
45
- r.set_encoding("UTF-8")
46
- r.read
50
+ cs = if File.exist?(archive_path)
51
+ read_archive
52
+ else
53
+ File.read(path)
47
54
  end
55
+
48
56
  if line
49
57
  cs.lines[0, line].join("")
50
58
  else
@@ -53,9 +61,13 @@ module Qwe::DB
53
61
  end
54
62
  end
55
63
 
64
+ def read_archive
65
+ Zstd.decompress(File.binread(archive_path)).force_encoding("UTF-8")
66
+ end
67
+
56
68
  def archive!
57
- file&.close
58
- ZSTDS::File.compress path, archive_path
69
+ File.binwrite(archive_path, Zstd.compress(read))
70
+ close
59
71
  FileUtils.rm_f(path)
60
72
  @file = nil
61
73
  end
@@ -65,7 +77,7 @@ module Qwe::DB
65
77
  end
66
78
 
67
79
  def close
68
- file&.close
80
+ file&.close unless file&.closed?
69
81
  end
70
82
  end
71
83
  end
data/lib/qwe/db/record.rb CHANGED
@@ -161,7 +161,7 @@ module Qwe::DB
161
161
  rec
162
162
  end
163
163
 
164
- def obj_eval(rb)
164
+ def evaluate(rb)
165
165
  object.instance_eval(rb)
166
166
  end
167
167
 
data/lib/qwe/db/worker.rb CHANGED
@@ -114,7 +114,7 @@ module Qwe::DB
114
114
  @@instance.work
115
115
  end
116
116
 
117
- def e(str)
117
+ def evaluate(str)
118
118
  instance_eval str
119
119
  end
120
120
  end
data/lib/qwe/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Qwe
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
data/qwe.gemspec CHANGED
@@ -28,5 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ["lib"]
29
29
 
30
30
  spec.add_dependency "drb", "~> 2.2.1"
31
- spec.add_dependency "ruby-zstds", "~> 1.3"
31
+ spec.add_dependency "zstd-ruby", "~> 1.5"
32
32
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qwe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - goose3228
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-01-04 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: drb
@@ -25,19 +24,19 @@ dependencies:
25
24
  - !ruby/object:Gem::Version
26
25
  version: 2.2.1
27
26
  - !ruby/object:Gem::Dependency
28
- name: ruby-zstds
27
+ name: zstd-ruby
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: '1.3'
32
+ version: '1.5'
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: '1.3'
39
+ version: '1.5'
41
40
  description: Object persistence with DRb access, manual or automatic RAM/disk switch,
42
41
  and transactions as ruby code.
43
42
  email:
@@ -58,6 +57,7 @@ files:
58
57
  - lib/puma/plugin/qwe.rb
59
58
  - lib/qwe.rb
60
59
  - lib/qwe/attribute.rb
60
+ - lib/qwe/console.rb
61
61
  - lib/qwe/db.rb
62
62
  - lib/qwe/db/commits_file.rb
63
63
  - lib/qwe/db/record.rb
@@ -79,7 +79,6 @@ licenses:
79
79
  - MIT
80
80
  metadata:
81
81
  source_code_uri: https://gitlab.com/goose3228/qwe
82
- post_install_message:
83
82
  rdoc_options: []
84
83
  require_paths:
85
84
  - lib
@@ -94,8 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
93
  - !ruby/object:Gem::Version
95
94
  version: '0'
96
95
  requirements: []
97
- rubygems_version: 3.5.16
98
- signing_key:
96
+ rubygems_version: 3.6.9
99
97
  specification_version: 4
100
98
  summary: Framework for in-RAM ruby applications
101
99
  test_files: []