macaw_framework 1.1.1 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +27 -0
- data/lib/macaw_framework/core/cron_runner.rb +2 -0
- data/lib/macaw_framework/version.rb +1 -1
- data/lib/macaw_framework.rb +50 -7
- data/sig/macaw_framework/macaw.rbs +3 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 206cdc56fc4e1027b3f1cc5d98b57a531c4043500cb1e99545b6e198c9b01f9d
|
4
|
+
data.tar.gz: 954b2f0bcbfea9bdc8e0a39362455e3c155e7b04f7b2accf786c6be658740c65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec8a983e02579327ef6987a86267094ed0d0384ed8f1da4c244b0c77d27b1ddae2de4e1ef94020ab90824055ae892f03f5884ce724ec596551622e25ee88d167
|
7
|
+
data.tar.gz: 9a90daa6f5884b4148728b89780a6fb118e071e932c6e437c4efa8f4f548b7624d021bb540e25f929d584c20e398974c27e962869e0d7337894466e0cf914a37
|
data/CHANGELOG.md
CHANGED
@@ -79,3 +79,15 @@
|
|
79
79
|
|
80
80
|
- Adding native cron jobs
|
81
81
|
- Documentation improvement
|
82
|
+
|
83
|
+
## [1.1.2] - 2023-05-31
|
84
|
+
|
85
|
+
- Fixing retry bug in cron jobs, where retries were made after an exception without waiting for interval
|
86
|
+
- Fixing another bug in cron jobs where an exception were thrown when start_delay were not set
|
87
|
+
- Documentation improvement
|
88
|
+
|
89
|
+
## [1.1.3] - 2023-05-31
|
90
|
+
|
91
|
+
- Adding start_without_server! method for starting the framework without running a web server
|
92
|
+
- Improving documentation
|
93
|
+
- Raising the number of default threads from 5 to 10
|
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/macaw_framework.svg)](https://badge.fury.io/rb/macaw_framework) ![CI Pipeline](https://github.com/ariasdiniz/macaw_framework/actions/workflows/main.yml/badge.svg?branch=main)
|
1
2
|
# MacawFramework
|
2
3
|
|
3
4
|
MacawFramework is a lightweight, easy-to-use web framework for Ruby designed to simplify the development of small to
|
@@ -8,6 +9,7 @@ provides developers with the essential tools to quickly build and deploy their a
|
|
8
9
|
* [Features](#features)
|
9
10
|
* [Installation](#installation)
|
10
11
|
* [Compatibility](#compatibility)
|
12
|
+
* [MacawFramework's Built-In Web Server](#macawframeworks-built-in-web-server)
|
11
13
|
* [Usage](#usage)
|
12
14
|
+ [Basic routing: Define routes with support for GET, POST, PUT, PATCH, and DELETE HTTP methods](#basic-routing-define-routes-with-support-for-get-post-put-patch-and-delete-http-methods)
|
13
15
|
+ [Caching: Improve performance by caching responses and configuring cache invalidation](#caching-improve-performance-by-caching-responses-and-configuring-cache-invalidation)
|
@@ -49,6 +51,28 @@ MacawFramework is built to be highly compatible, since it uses only native Ruby
|
|
49
51
|
|
50
52
|
- **JRuby**: MacawFramework is also compatible with JRuby, a version of Ruby that runs on the Java Virtual Machine (JVM).
|
51
53
|
|
54
|
+
Sure, here's a rewritten section for your README:
|
55
|
+
|
56
|
+
## MacawFramework's Built-In Web Server
|
57
|
+
|
58
|
+
MacawFramework includes a built-in web server based on Ruby's TCPServer class, providing a lightweight yet robust solution for serving your web applications. It incorporates features such as SSL security and a thread-based architecture, offering a balance of simplicity, performance, and robustness.
|
59
|
+
|
60
|
+
### Key Features
|
61
|
+
|
62
|
+
- **SSL Security**: Our server integrates SSL security, offering secure communication for your applications. By providing a valid SSL context, the built-in TCPServer will be wrapped in OpenSSL's SSLServer, adding an essential secure transport layer to your web server.
|
63
|
+
|
64
|
+
- **Thread-based Architecture**: We employ a thread-based model where a specified number of worker threads are used to handle client connections. Incoming connections are queued in a work queue, where they are then processed by the worker threads, ensuring fair scheduling and load distribution.
|
65
|
+
|
66
|
+
- **Thread Pool Management**: We make use of Ruby's built-in synchronization constructs, using a Mutex to safely manage the worker threads pool. A maintenance routine periodically checks the health of the worker threads, respawning any that have died, ensuring consistent server performance.
|
67
|
+
|
68
|
+
- **Graceful Shutdown**: Our server is designed to gracefully shut down when required, making sure all pending connections in the work queue are processed before closing the worker threads and the server itself. This ensures that no client requests are abruptly terminated, providing a smooth user experience.
|
69
|
+
|
70
|
+
It's worth noting that while our threading model is simple and effective, it has some limitations. The number of concurrent connections it can handle is limited by the number of worker threads, and it could be susceptible to slow clients, which could tie up a worker thread and reduce the server's capacity. However, for JRuby and TruffleRuby users, this threading model can leverage true system-level threading due to the lack of a Global Interpreter Lock (GIL), potentially providing better performance on multi-core systems and handling larger numbers of concurrent connections more efficiently.
|
71
|
+
|
72
|
+
Despite these trade-offs, MacawFramework's built-in web server offers a good balance for most web applications, particularly for small to medium scale deployments. For larger-scale applications with high concurrency demands, consider supplementing the built-in server with an event-driven architecture or utilizing a third-party server solution better suited for such scenarios.
|
73
|
+
|
74
|
+
In summary, MacawFramework's built-in web server provides a straightforward, efficient, and secure solution for running your web applications, requiring minimal configuration and making deployment a breeze.
|
75
|
+
|
52
76
|
## Usage
|
53
77
|
|
54
78
|
### Basic routing: Define routes with support for GET, POST, PUT, PATCH, and DELETE HTTP methods
|
@@ -166,6 +190,9 @@ Values for interval and start_delay are in seconds.
|
|
166
190
|
|
167
191
|
**Caution: Defining a lot of jobs with low interval can severely degrade performance.**
|
168
192
|
|
193
|
+
If you want to build an application with just cron jobs, that don't need to run a web server, you can start
|
194
|
+
MacawFramework without running a web server with `start_without_server!` method, instead of `start!`.
|
195
|
+
|
169
196
|
### Tips
|
170
197
|
|
171
198
|
- The automatic logging and log aspect are now optional. To disable them, simply start Macaw with `custom_log` set to nil.
|
@@ -16,6 +16,7 @@ class CronRunner
|
|
16
16
|
# @param {String} job_name
|
17
17
|
# @param {Proc} block
|
18
18
|
def start_cron_job_thread(interval, start_delay, job_name, &block)
|
19
|
+
start_delay ||= 0
|
19
20
|
raise "interval can't be <= 0 and start_delay can't be < 0!" if interval <= 0 || start_delay.negative?
|
20
21
|
|
21
22
|
@logger&.info("Starting thread for job #{job_name}")
|
@@ -39,6 +40,7 @@ class CronRunner
|
|
39
40
|
sleep(sleep_time)
|
40
41
|
rescue StandardError => e
|
41
42
|
@logger&.error("Error executing cron job with name #{name}: #{e.message}")
|
43
|
+
sleep(interval)
|
42
44
|
end
|
43
45
|
end
|
44
46
|
sleep(1)
|
data/lib/macaw_framework.rb
CHANGED
@@ -31,7 +31,7 @@ module MacawFramework
|
|
31
31
|
@config = JSON.parse(File.read("application.json"))
|
32
32
|
@port = @config["macaw"]["port"] || 8080
|
33
33
|
@bind = @config["macaw"]["bind"] || "localhost"
|
34
|
-
@threads = @config["macaw"]["threads"] ||
|
34
|
+
@threads = @config["macaw"]["threads"] || 10
|
35
35
|
unless @config["macaw"]["cache"].nil?
|
36
36
|
@cache = MemoryInvalidationMiddleware.new(@config["macaw"]["cache"]["cache_invalidation"].to_i || 3_600)
|
37
37
|
end
|
@@ -56,7 +56,12 @@ module MacawFramework
|
|
56
56
|
# with the respective path.
|
57
57
|
# @param {String} path
|
58
58
|
# @param {Proc} block
|
59
|
-
# @
|
59
|
+
# @example
|
60
|
+
#
|
61
|
+
# macaw = MacawFramework::Macaw.new
|
62
|
+
# macaw.get("/hello") do |context|
|
63
|
+
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
64
|
+
# end
|
60
65
|
def get(path, cache: false, &block)
|
61
66
|
map_new_endpoint("get", cache, path, &block)
|
62
67
|
end
|
@@ -67,7 +72,12 @@ module MacawFramework
|
|
67
72
|
# @param {String} path
|
68
73
|
# @param {Boolean} cache
|
69
74
|
# @param {Proc} block
|
70
|
-
# @
|
75
|
+
# @example
|
76
|
+
#
|
77
|
+
# macaw = MacawFramework::Macaw.new
|
78
|
+
# macaw.post("/hello") do |context|
|
79
|
+
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
80
|
+
# end
|
71
81
|
def post(path, cache: false, &block)
|
72
82
|
map_new_endpoint("post", cache, path, &block)
|
73
83
|
end
|
@@ -77,7 +87,12 @@ module MacawFramework
|
|
77
87
|
# with the respective path.
|
78
88
|
# @param {String} path
|
79
89
|
# @param {Proc} block
|
80
|
-
# @
|
90
|
+
# @example
|
91
|
+
#
|
92
|
+
# macaw = MacawFramework::Macaw.new
|
93
|
+
# macaw.put("/hello") do |context|
|
94
|
+
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
95
|
+
# end
|
81
96
|
def put(path, cache: false, &block)
|
82
97
|
map_new_endpoint("put", cache, path, &block)
|
83
98
|
end
|
@@ -87,7 +102,12 @@ module MacawFramework
|
|
87
102
|
# with the respective path.
|
88
103
|
# @param {String} path
|
89
104
|
# @param {Proc} block
|
90
|
-
# @
|
105
|
+
# @example
|
106
|
+
#
|
107
|
+
# macaw = MacawFramework::Macaw.new
|
108
|
+
# macaw.patch("/hello") do |context|
|
109
|
+
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
110
|
+
# end
|
91
111
|
def patch(path, cache: false, &block)
|
92
112
|
map_new_endpoint("patch", cache, path, &block)
|
93
113
|
end
|
@@ -97,7 +117,12 @@ module MacawFramework
|
|
97
117
|
# with the respective path.
|
98
118
|
# @param {String} path
|
99
119
|
# @param {Proc} block
|
100
|
-
# @
|
120
|
+
# @example
|
121
|
+
#
|
122
|
+
# macaw = MacawFramework::Macaw.new
|
123
|
+
# macaw.delete("/hello") do |context|
|
124
|
+
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
125
|
+
# end
|
101
126
|
def delete(path, cache: false, &block)
|
102
127
|
map_new_endpoint("delete", cache, path, &block)
|
103
128
|
end
|
@@ -108,7 +133,13 @@ module MacawFramework
|
|
108
133
|
# @param {Integer?} start_delay
|
109
134
|
# @param {String} job_name
|
110
135
|
# @param {Proc} block
|
111
|
-
|
136
|
+
# @example
|
137
|
+
#
|
138
|
+
# macaw = MacawFramework::Macaw.new
|
139
|
+
# macaw.setup_job(interval: 60, start_delay: 60, job_name: "job 1") do
|
140
|
+
# puts "I'm a cron job that runs every minute"
|
141
|
+
# end
|
142
|
+
def setup_job(interval: 60, start_delay: 0, job_name: "job_#{SecureRandom.uuid}", &block)
|
112
143
|
@cron_runner ||= CronRunner.new(self)
|
113
144
|
@jobs ||= []
|
114
145
|
@cron_runner.start_cron_job_thread(interval, start_delay, job_name, &block)
|
@@ -142,6 +173,18 @@ module MacawFramework
|
|
142
173
|
end
|
143
174
|
end
|
144
175
|
|
176
|
+
##
|
177
|
+
# This method is intended to start the framework
|
178
|
+
# without an web server. This can be useful when
|
179
|
+
# you just want to keep cron jobs running, without
|
180
|
+
# mapping any HTTP endpoints.
|
181
|
+
def start_without_server!
|
182
|
+
@macaw_log.nil? ? puts("Application starting") : @macaw_log.info("Application starting")
|
183
|
+
loop { sleep(3600) }
|
184
|
+
rescue Interrupt
|
185
|
+
@macaw_log.nil? ? puts("Macaw stop flying for some seeds.") : @macaw_log.info("Macaw stop flying for some seeds.")
|
186
|
+
end
|
187
|
+
|
145
188
|
private
|
146
189
|
|
147
190
|
def server_loop(server)
|
@@ -3,6 +3,7 @@ module MacawFramework
|
|
3
3
|
@bind: String
|
4
4
|
@cache: untyped
|
5
5
|
@config: Hash[String, untyped]
|
6
|
+
@cron_runner: CronRunner
|
6
7
|
@endpoints_to_cache: Array[String]
|
7
8
|
@macaw_log: Logger?
|
8
9
|
|
@@ -31,6 +32,8 @@ module MacawFramework
|
|
31
32
|
|
32
33
|
def put: -> nil
|
33
34
|
|
35
|
+
def setup_job: -> nil
|
36
|
+
|
34
37
|
def start!: -> nil
|
35
38
|
|
36
39
|
private
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: macaw_framework
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aria Diniz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prometheus-client
|