emcien / iso_latte Goto Github PK
View Code? Open in Web Editor NEWRuby gem for isolating code execution into a subprocess
License: BSD 3-Clause "New" or "Revised" License
Ruby gem for isolating code execution into a subprocess
License: BSD 3-Clause "New" or "Revised" License
I am getting TypeError: no _dump_data is defined for class Binding
from the Marshal.dump
in the exception pipe code. This seems to be because e.cause
produces another exception, which also has __better_errors_bindings_stack
defined on it.
I guess I'll need to recurse? It's in the fork, so it shouldn't hurt anything.
Right now I'm not sure that it will work on other rubies - installing and running specs on various platforms would be useful. #4's matrix should probably be done afterward.
Initially we just want normal auto-tests, but a build-matrix to test on other platforms would be nice too.
@nevinera How to load environment into fork to use ActiveRecord at here.
Ex:
IsoLatte.fork(
stderr: "tmp/suberr.txt",
finish: ->(success, rc) { puts "Finished. Success? #{success}" },
success: ->() { puts "Was successful" },
kill: ->() { puts "Received a SIGKILL" },
fault: ->() { puts "Received a SIGABRT, probably a segmentation fault" },
exit: ->(rc) { puts "subprocess exited explicitly with #{rc}" }
) do
results = Product.search_by(categories, keywords, page).results
end
This is very cool. I timeout option would be very useful too. That kinda covers the last condition of "my subprocess has been zombified and doesn't like it's ever going to return".
Hello,
i propose to add "detach" feature, which should be only an option to existing interface.
The rationale for this feature is:
Usage example with rabbitmq:
require 'iso_latte'
require 'bunny'
Message = Struct.new(:meta, :payload)
Job = Struct.new(:msg) do
def perform
$stderr.puts("Performing #{msg.payload.inspect}")
sleep(rand(5)+1)
$stderr.puts("Done!")
end
end
conn = Bunny.new.start
channel = conn.create_channel
# consumer allowed to be sent up to 5 messages without acknowledgements
channel.prefetch(5)
channel.queue('jobs').subscribe(manual_ack: true) do |_, meta, payload|
msg = Message.new(meta, payload)
IsoLatte.fork(detach: true,
finish: proc { |success,rc| success ? msg.meta.ack : msg.meta.reject }) do
conn.close
Job.new(msg).perform
end
end
In result i'll have worker supervisor, which able to handle upto 5 jobs simultaneously. Each job starts from scratch! no membloats! shitty jobs code protection!
Right now the fork
function accepts a 'timeout' option, and after that long has elapsed it will send a SIGKILL to the child.
Two approaches would be better.
We could reasonably combine the two by allowing a set of timeouts and signals to be supplied, like { kill: 100, hup: 58 }
, and manage all of the timeouts. Then we could interpret timeout: 10
to mean timeout: { kill: 11, term: 10 }
.
Right now we have a pipe open between the parent and child so that any ruby exceptions encountered can be marshaled back across it and re-raised. It would be equally useful to be able to conveniently return a result from the block.
Add an option to 'retrieve_result' (it'll default to false), which will cause a result-pipe to be opened, and the child process to marshal and send the result of the block back to the parent. The result will be available instead of the child's status object, and will be nil if the child does not complete successfully and without exiting.
Rather than the current threading approach, which will require careful thought when any change is made to the timeout code, we can move to a more explicit approach:
Process.waitpid2
and Timeout.timeout
can each run in a thread - rather than the current blocking wait, we'll use Process::WNOHANG
and sleep-loop, checking a queue and then trying a wait every quarter-second. When the timeout goes off, it'll go off in a thread, and push a :timeout
onto the queue. This approach prevents either thread from interrupting the other, and makes adding complexity to the timeout code (as in #3) much more reasonable.
Suggestion from moomaka here.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.