Yii2 cli and pcntl_fork - command-line

I have a Yii2 script that runs forever to execute tasks on request.
Some tasks (as task2) should be performed in a seperate forked process:
switch ($command) {
case 'task1':
echo "hello";
break;
case 'task2':
if ( ($pid=pcntl_fork()) == -1 )
throw new Exception("fork failed");
if ($pid==0) {
// we are child process
// perform task here
...
exit(0);
}
break;
}
}
Doing such a fork, the database connection goes lost in the parent. There are some workarounds on the PHP level, but how to handle this on the Yii2 level?
Can we activate auto-reconnect in Yii2 by configuration?

Related

NWEthernetChannel not working as expected

The "Advances in Networking" talk for WWDC2019 featured a new class, introduced in Mac OS X 10.15 called NWEthernetChannel to monitor a custom (non-IP) protocol. This is for MacOS.
I am interested in monitoring Cisco Discovery Protocol (CDP) packets, however, the class is not working as expected - the receiveHandler is not receiving any data.
What I verified:
NWEthernetChannel is alive and in the ready state, monitoring the active NWInterface called eth0.
As per the documentation, the com.apple.developer.networking.custom-protocol entitlement is set.
I verified the same logic using sudo tcpdump -nn -v -i en0 -s 1500 'ether[20:2] == 0x2000'. This returned the expected result.
Please see my implementation below:
self._ethernetChannel = NWEthernetChannel(on: self._ethernetInterface!, etherType: 0x2000)
self._ethernetChannel!.stateUpdateHandler = {state in switch state {
case .ready:
NSLog("ready");
break;
case .waiting(let error as NWError):
print("Waiting:", error);
break;
case .failed(let error as NWError):
print("Failed:", error);
break;
case .cancelled:
print("cancelled");
break;
case .preparing:
print("preparing");
break;
case .setup:
print("setup");
default:
NSLog("default");
break;
}}
self._ethernetChannel!.receiveHandler = {(packetData, vlanTag, localAddress, remoteAddress) in
print("received data");
};
self._ethernetChannel!.start(queue: .main);
Can someone shed some light?

How can I check the connection of Mongoid

Does Mongoid has any method like ActiveRecord::Base.connected??
I want to check if the connection that's accessible.
We wanted to implement a health check for our running Mongoid client that tells us whether the established connection is still alive. This is what we came up with:
Mongoid.default_client.database_names.present?
Basically it takes your current client and tries to query the databases on its connected server. If this server is down, you will run into a timeout, which you can catch.
My solution:
def check_mongoid_connection
mongoid_config = File.read("#{Rails.root}/config/mongoid.yml")
config = YAML.load(mongoid_config)[Rails.env].symbolize_keys
host, db_name, user_name, password = config[:host], config[:database], config[:username], config[:password]
port = config[:port] || Mongo::Connection::DEFAULT_PORT
db_connection = Mongo::Connection.new(host, port).db(db_name)
db_connection.authenticate(user_name, password) unless (user_name.nil? || password.nil?)
db_connection.collection_names
return { status: :ok }
rescue Exception => e
return { status: :error, data: { message: e.to_s } }
end
snrlx's answer is great.
I use following in my puma config file, FYI:
before_fork do
begin
# load configuration
Mongoid.load!(File.expand_path('../../mongoid.yml', __dir__), :development)
fail('Default client db check failed, is db connective?') unless Mongoid.default_client.database_names.present?
rescue => exception
# raise runtime error
fail("connect to database failed: #{exception.message}")
end
end
One thing to remind is the default server_selection_timeout is 30 seconds, which is too long for db status check at least in development, you can modify this in your mongoid.yml.

Why do I get an MSPL exception "ProxyRequest only valid for sipRequest"

I'm writing a Lync MSPL application using a manifest and a windows service. In my manifest.am I have the following code:
<?xml version="1.0"?>
<r:applicationManifest
r:appUri="http://www.company.no/LyncServerFilter"
xmlns:r="http://schemas.microsoft.com/lcs/2006/05">
<r:requestFilter methodNames="ALL"
strictRoute="true"
domainSupported="false"/>
<r:responseFilter reasonCodes="ALL"/>
<r:proxyByDefault action="true" />
<r:allowRegistrationBeforeUserServices action="true" />
<r:splScript>
<![CDATA[
callId = GetHeaderValues("Call-ID");
cseq = GetHeaderValues("CSeq");
content = "";
sstate = GetHeaderValues("subscription-state");
xevent = GetHeaderValues("Event");
xdir = GetHeaderValues("Direction");
xexp = GetHeaderValues("Session-Expires");
referto = GetHeaderValues("Refer-To");
if (sipRequest)
{
if (sipRequest.Method == "INVITE") {
if (ContainsString(sipRequest.Content, "m=audio", true)) {
content = "audio";
}
else if (ContainsString(sipRequest.Content, "m=video", true)) {
content = "video";
}
else if (ContainsString(sipRequest.Content, "m=message", true)) {
content = "message";
}
else if (ContainsString(sipRequest.Content, "m=application", true)) {
content = "application";
}
else {
content = "unknown";
}
}
else if (sipRequest.Method == "NOTIFY" || sipRequest.Method == "BENOTIFY") {
content = sipRequest.Content;
}
DispatchNotification("OnRequest", sipRequest.Method, sipMessage.From, sipMessage.To, callId, cseq, content, xdir, xevent, sstate, xexp, referto);
if (sipRequest) {
ProxyRequest();
}
}
else if(sipResponse) {
DispatchNotification("OnResponse", sipResponse.StatusCode, sipResponse.StatusReasonPhrase, sipMessage.From, sipMessage.To, callId, cseq, content, xdir, xevent, sstate, xexp, referto);
ProxyResponse();
}
]]></r:splScript>
</r:applicationManifest>
I'm getting the following errormessage in Eventlog on Lync Front End server:
Lync Server application MSPL script execution aborted because of an error
Application Uri at 'http://www.company.no/LyncServerFilter', at line 60
Error: 0x80070057 - The parameter is incorrect
Additional information: ProxyRequest only valid for sipRequest
Line 60 is where I call ProxyRequest:
if (sipRequest) {
ProxyRequest();
}
Questions:
Why does the errormessage say that ProxyRequest is only valid for a sipRequest? I'm checking that it is a sipMessage right?
Can I remove my call to ProxyRequest() since I have set proxyByDefault=true? Does the DistpathNotification-method "handle" the method (swallow it), or will the message be proxied by default? The code "works" when I remove the call to ProxyRequest(), but I'm not sure what the consequences are...
The ProxyRequest method takes a argument of the uri, which is why you are getting the compile error message.
So you should be calling it like:
ProxyRequest(""); // send to the URI specified in the request itself
Removing it effectivity does the same thing as per your proxyByDefault setting being set to true:
If true, the server automatically proxies any messages that are not handled by the application. If false, the message is dropped and applications that follow this application in the application execution order will not receive it. The default value is true.
As a side-note, you can use compilespl.exe, which comes as part of the Lync Server SDK to verify that your MSPL script is correct before trying to start it on the lync server.
Check out this link in the 'Compile the MSPL application separately' section.

Perl process crashes after handling signal

I'm trying to make rereading config file for simple perl daemon on SIGHUP.
I'm trying
use sigtrap qw/handler rereadconf HUP/;
but after executing "rereadconf" procedure process stops
i'm also trying
%SIG{HUP} = \&rereadconf;
sub rereadconf{
.... mycode
print "procedure executed\n";
};
but result was the same, after executing procedure program stops.
So how can i make that process continue execution after signal handling?
Your program exits because the accept returns false because it got interrupted by a signal. You want
while (1) {
my $client = $srv->accept();
if (!$client) {
next if $!{EINTR};
die(sprintf(STDERR "[%s] accept: %s\n", basename($0), $!));
}
print(STDERR "accepted new client\n");
serve_client($client);
}

Resque Workers on Heroku locked out of Postgres DB SSL- no fix yet

I'm using resque/redis on heroku to send emails as a background job. It works fine for the first email I send, but after that I get the error: (ActiveRecord::StatementInvalid: PG::Error: SSL error: decryption failed or bad record mac :) ...
I've seen the other questions/answers that say to add to an initializer:
Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }
OR
Resque.before_fork = Proc.new { ActiveRecord::Base.establish_connection }
However, I have done this (and tried any other thing I can think of) and I'm still getting the same error. I have run the code with only before_fork and only after_fork to no avail.
I am also using APN_sender to send apple push notifications. The workers for these have had no problems (but I'm calling default Heroku workers to do these rather than Resque workers).
Here are my relevant files, please help! This is my first SO question as well.. apologies if it's not done perfectly.
#config/resque.rb
after_fork do |server, worker, resque|
logger.info("Got to after_fork in resque.rb config file")
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
--------------------
#config/initializers/resque.rb
require 'resque'
require 'resque/server'
heroku_environments = ["staging", "production"]
rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
rails_env = ENV['RAILS_ENV'] || 'development'
#confusing wording.. determines whether or not we are in Production, tested and working
unless heroku_environments.include?(rails_env)
resque_config = YAML.load_file(rails_root + '/config/resque.yml')
Resque.redis = resque_config[rails_env]
else
uri = URI.parse(ENV["REDISTOGO_URL"] || "redis://localhost:6379/")
Resque.redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
end
----------------------
#resque.rake
require 'resque/tasks'
task "resque:setup" => :environment do
ENV['QUEUE'] = '*'
Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }
Resque.before_fork = Proc.new { ActiveRecord::Base.establish_connection }
end
task "apn:setup" => :environment do
ENV['QUEUE'] = '*'
end
desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"
desc "Alias for apn:work (To run workers on Heroku)"
task "jobs:work" => "apn:work"
-----------------------
#Sending the email
#event.guests.each do |g|
Resque.enqueue(MailerCallback, "Notifier", :time_change, #event.id, g.id)
end
I am running one Heroku worker and one Resque worker from the Heroku ps:scale command. As I said, the first email sends error-free, and then any emails after get the above error.
Thanks in advance!
Mike
OK, so couldn't figure this out...
Switched over to delayed job and it's working much better. A little frustrating that I can't send push notifications with apn_sender anymore, but apn_on_rails is working fine.
Weird problem, still curious...