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 +4 -4
- data/DOCS.md +1 -1
- data/Gemfile.lock +3 -5
- data/README.md +16 -4
- data/exe/qwe +3 -25
- data/lib/qwe/attribute.rb +1 -1
- data/lib/qwe/console.rb +66 -0
- data/lib/qwe/db/commits_file.rb +26 -14
- data/lib/qwe/db/record.rb +1 -1
- data/lib/qwe/db/worker.rb +1 -1
- data/lib/qwe/version.rb +1 -1
- data/qwe.gemspec +1 -1
- metadata +7 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9163afb748f542c3cee0749fa5cb182100c2c46c5eb52c7834dd6a9e9928e569
|
4
|
+
data.tar.gz: f36a49f10487cae9d6c6caeb5774946355d072e832d4139f6e3f74af8b65b8dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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.
|
4
|
+
qwe (0.0.1)
|
5
5
|
drb (~> 2.2.1)
|
6
|
-
ruby
|
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
|
-
|
4
|
-
|
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][:
|
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
|
-
|
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) + "
|
119
|
+
reader.stage "self.#{name} = " + init_or_default_stage(:default) + " if @#{name}.nil?"
|
120
120
|
end
|
121
121
|
|
122
122
|
add(:convert) do
|
data/lib/qwe/console.rb
ADDED
@@ -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
|
data/lib/qwe/db/commits_file.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
24
|
+
if !file
|
22
25
|
log "Write #{str} to archived commits file #{path}, unpacking"
|
23
|
-
|
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 =
|
45
|
-
|
46
|
-
|
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
|
-
|
58
|
-
|
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
data/lib/qwe/db/worker.rb
CHANGED
data/lib/qwe/version.rb
CHANGED
data/qwe.gemspec
CHANGED
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.
|
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:
|
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
|
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.
|
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.
|
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.
|
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: []
|