Is it possible to obtain "current_time" in rufus-scheduler - ruby

Supposed I scheduled a job with rufus-scheduler like below:
scheduler.cron '* * * * * UTC' do |job|
...
end
I can retrieve some useful info from 'job' variable. For example, next_time shows when the next run is scheduled at. I am wondering if a similar value is available for "current_time". Reason: for various reasons (threads, system load, etc) a job could be executed with a small amount of delay. I want to know the exact time the job is meant to have started. If I retrieve system time by Time.new, that will not be exact.
Is there a way? I tried awesome_print the job variable. It seems the value I am looking for is not available.
jruby-1.7.19 :017 > #<Rufus::Scheduler::CronJob:0x3951b84e #unscheduled_at=nil, #first_at=nil, #opts={}, #last_time=2016-07-28 01:35:00 +0800, #tags=[], #mean_work_time=0.0, #callable=#<Proc:0x2ee23f1d#(irb):14>, #last_at=nil, #count=1, #scheduled_at=2016-07-28 01:34:09 +0800, #handler=#<Proc:0x2ee23f1d#(irb):14>, #paused_at=nil, #local_mutex=#<Mutex:0x79da0f7>, #locals={}, #times=nil, #scheduler=#<Rufus::Scheduler:0x7dc7d255 #mutexes={}, #scheduler_lock=#<Rufus::Scheduler::NullLock:0x49c20af6>, #paused=false, #opts={}, #work_queue=#<Queue:0x625dc24e>, #jobs=#<Rufus::Scheduler::JobArray:0x797fc155 #mutex=#<Mutex:0x501b94b9>, #array=[#<Rufus::Scheduler::CronJob:0x3951b84e ...>]>, #trigger_lock=#<Rufus::Scheduler::NullLock:0x42c126c5>, #started_at=2016-07-28 01:33:36 +0800, #thread_key="rufus_scheduler_2068", #stderr=#<IO:fd 2>, #max_work_threads=28, #frequency=0.3, #thread=#<Thread:0x16d871c0 sleep>>, #cron_line=#<Rufus::Scheduler::CronLine:0x6156f1b0 #seconds=[0], #weekdays=nil, #hours=nil, #timezone="UTC", #days=nil, #minutes=nil, #original="* * * * * UTC", #months=nil, #monthdays=nil>, #last_work_time=0.0, #id="cron_1469640849.047_961656910", #original="* * * * * UTC", #next_time=2016-07-27 17:36:00 +0000>

Added a Job#previous_time
https://github.com/jmettraux/rufus-scheduler/commit/43f1016859a43ea7f138404c1e5d864048f24959
scheduler.every('10s') do |job|
puts "job scheduled for #{job.previous_time} triggered at #{Time.now}"
puts "next time will be around #{job.next_time}"
puts "."
end

A job's #next_time is supposed to hold the trigger time until the #post_trigger hook gets called.

Related

AWS cron expression OK, lambda not triggered

I have set the following cron expression in AWS (CloudWatch trigger).
0 */5 7-12,1pm-11pm ? * MON,TUE,WED,THU,FRI
In expression generator, I get for very similar expresssion (7-23 intead of the hours )
At second :00, every 5 minutes starting at minute :00, every hour between 07am and 23pm, on every Monday, Tuesday, Wednesday, Thursday and Friday, every month
as expected.
However, it is not triggered. I don't see anything in the log.
Why is that? (trigger is enabled of course)
Thanks.
When you create CloudWatch Event Rule, or EventBridge Event Rule (is what AWS calls these days) and select Lambda function as target, there are 2 main points that you need to consider:
CRON SCHEDULE
You need to specify the cron schedule and this schedule timezone is UTC+0.
I assume that you are in different timezone and observe there is not any triggers since the next trigger time has not been reached yet.
RESOUCE-BASED POLICY
There is another chance that you need to check is about permissions, you need to concern is Lambda function's Resource Based Policy.
Go to AWS Console, you can check your Lambda's permission tab and review your permissions which is required to allow your Event Rule triggers.
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "AWSEvents",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:<REGION>:<ACCOUNT_ID>:function:<FUNCTION_NAME>",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:events:<REGION>:<ACCOUNT_ID>:rule/<RULE_NAME>"
}
}
}
]
}
Well, the expression wasn't right.
It considers minutes only and the */5 confused it too maybe. Not sure about the * at the end.
0/5 7-23 ? * MON-FRI * - this works
To debug triggers, there is "Rules" section in the log service, where you can see the next executions.
Since the CRON expression is in UTC time format. Could you please check if there is any time difference b/w your standard time and UTC time?
And change the expression accordingly.

Springboot chaos-monkey assaults [killApplicationActive and memoryActive] not working

I am using Springboot 2.3.1.RELEASE and chaos monkey its working fine for latencyActive and exceptionsActive.
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>chaos-monkey-spring-boot</artifactId>
<version>2.2.0</version>
</dependency>
Following two assaults not working
Kill application
chaos.monkey.assaults.killApplicationActive=true
chaos.monkey.assaults.level=3
Memory
chaos.monkey.assaults.memoryActive=true
chaos.monkey.assaults.memoryMillisecondsHoldFilledMemory=90000
chaos.monkey.assaults.memoryMillisecondsWaitNextIncrease=1000
chaos.monkey.assaults.memoryFillIncrementFraction=90.15
chaos.monkey.assaults.memoryFillTargetFraction=90.25
App kill and memory kill attacks need the attribute runtimeAssaultCronExpression set to a valid cron expression like " * * * * * * ". By default it is set to "OFF"
See documentation: https://codecentric.github.io/chaos-monkey-spring-boot/2.2.0/#_appkiller_assault
To Kill an application manually follow the below step:
1) Create the assault by:
POST: https://{{server-address}}/{{app-name}}/actuator/chaosmonkey/assaults
{
"level": 1,
"deterministic": false,
"latencyActive": false,
"exceptionsActive": false,
"killApplicationActive": true,
"memoryActive": false,
"cpuActive": false }
2) Run the created assault by:
POST: https://{{server-address}}/{{app-name}}/actuator/chaosmonkey/assaults/runtime/attack
Use property value for "chaos.monkey.assaults.runtime.scope.assault.cron.expression" as cron expression like */1 * * * * ? or any valid cron expression, to enable chaos monkey runtime assaults on a schedule.
Use property value as OFF otherwise(also default value)
links:
https://codecentric.github.io/chaos-monkey-spring-boot/2.1.0/#configuration
https://www.programmersought.com/article/11861551911/
LatencyActive and ExceptionsActive assaults are low impact assault(Request type), whereas KillApp and Memory are high impact assaults(Runtime assault). So Request type assault can be triggered just by loading them whereas Runtime assault requires an additional step after loading them.
Trigger this Http endpoint and that should execute the assault:
/chaosmonkey/assaults/runtime/attack

Trailblazer: Which step caused my operation to fail?

Given an operation like
class MyOperation < Trailblazer::Operation
step :do_a!
step :do_b!
def do_a(options, **)
false
end
def do_b(options, **)
true
end
end
and the result of run(MyOperation), how can I tell which step of the operation failed?
If the result object doesn't contain this info by default, what's a good way to add it?
There is this gem now which provides operation specific debugging utilities - https://github.com/trailblazer/trailblazer-developer
It allows you to see exactly which step raised the exception or which step caused the track to change from success to failure.
Trailblazer::Developer.wtf?(MyOperation, options)
It will print the trace of steps on STDOUT/Logger.

Validation Error in ODOO

How to stop raising validation error in ODOO 10
For example in project.py file I want to stop raising this validation error :
#api.constrains('date_start', 'date_end')
def _check_dates(self):
if any(self.filtered(lambda task: task.date_start and task.date_end and task.date_start > task.date_end)):
raise ValidationError(_('Error ! Task starting date must be lower than its ending date.'))
You can disable that warning by overriding the function. Try below code,
#api.constrains('date_start', 'date_end')
def _check_dates(self):
if any(self.filtered(lambda task: task.date_start and task.date_end and task.date_start > task.date_end)):
pass;
#raise ValidationError(_('Error ! Task starting date must be lower than its ending date.'))
Hope it will help you.

Ruby Timeout Module - Timeout doesn't execute

I came across the Timeout module in Ruby, and wanted to test it out. I looked at their official source code at http://ruby-doc.org/stdlib-2.1.1/libdoc/timeout/rdoc/Timeout.html
Here is the code I had
require 'timeout'
require 'benchmark'
numbers = [*1..80]
Timeout::timeout(5) { numbers.combination(5).count }
=> 24040016
I did some benchmarking tests, and got the following.
10.828000 0.063000 10.891000 11.001676
According to the documentation, this method is supposed to return an exception if the block is not executed within 5 seconds. If it is executed within the time frame, it will return the result of the code block
For what it's worth, I've tried timeout with 1 second, instead of 5 seconds, and I still get returned the result of the code block.
Here is the official documentation
timeout(sec, klass=nil)
Performs an operation in a block, raising an error if it takes longer than sec seconds to complete.
sec: Number of seconds to wait for the block to terminate. Any number may be used,
including Floats to specify fractional seconds. A value of 0 or nil will execute the
block without any timeout.
klass: Exception Class to raise if the block fails to terminate in sec seconds. Omitting
will use the default, Timeout::Error
I am mystified as to why this doesn't work.
The problem is the way MRI (Matz's Ruby Implementation) thread scheduling works. MRI uses a GIL (Global Interpreter Lock), which in practice means only one thread is truly running at a time.
There are some exception, but for the majority of the time there is only one thread executing Ruby code at any one time.
Normally you do not notice this, even during heavy computations that consume 100% CPU, because the MRI keeps time-slicing the threads at regular intervals so that each thread gets a turn to run.
However there's one exception where time-slicing isn't active and that's when a Ruby thread is executing native C-code instead of Ruby code.
Now it so happens that Array#combination is implemented in pure C:
[1] pry(main)> show-source Array#combination
From: array.c (C Method):
static VALUE
rb_ary_combination(VALUE ary, VALUE num)
{
...
}
When we combine this knowledge with how Timeout.timeout is implemented we can start to get a clue of what is happening:
[7] pry(main)> show-source Timeout#timeout
From: /opt/ruby21/lib/ruby/2.1.0/timeout.rb # line 75:
75: def timeout(sec, klass = nil) #:yield: +sec+
76: return yield(sec) if sec == nil or sec.zero?
77: message = "execution expired"
78: e = Error
79: bl = proc do |exception|
80: begin
81: x = Thread.current
82: y = Thread.start {
83: begin
84: sleep sec
85: rescue => e
86: x.raise e
87: else
88: x.raise exception, message
89: end
90: }
91: return yield(sec)
92: ensure
93: if y
94: y.kill
95: y.join # make sure y is dead.
96: end
97: end
98: end
99: ...
1xx: end
Your code running Array.combination most likely actually starts executing even BEFORE the timeout thread runs sleep sec on line 84. Your code is launched on line 91 through yield(sec).
This means the order of execution actually becomes:
1: [thread 1] numbers.combination(5).count
# ...some time passes while the combinations are calculated ...
2: [thread 2] sleep 5 # <- The timeout thread starts running sleep
3: [thread 1] y.kill # <- The timeout thread is instantly killed
# and never times out.
In order to make sure the timeout thread starts first you can try this, which will most likely trigger the timeout exception this time:
Timeout::timeout(5) { Thread.pass; numbers.combination(5).count }
This is because by running Thread.pass you allow the MRI scheduler to start and run the code on line 82 before the native combination C-code executes. However even in this case the exception won't be triggered until combination exits because of the GIL.
There is no way around this unfortunately. You would have to use something like JRuby instead, which has real concurrent threads. Or you could run the combination calculation in a Process instead of a thread.

Resources