How can I trigger a fast active/passive redu switch if my active machine is shutting down?
Within normal circumstances there is no need to be concerned about correct active/passive switch because WinCC OA is handling this automatically. But there could be some exceptions where the automated active/passive switch is triggered to late.
One of these exceptions is a shutdown process of the active machine.
The reason is that the CalculateState Script is unable to update the error state of the machine which is currently shutting down.
This will lead to a situation where the shutting down machine remains active until the connection between both Event Managers is broken. This could take up to approximate 30 seconds. Within this time period the system is in a situation where the shutting down and still active machine is unable the handle these message correctly and the passive system is dropping these messages (because it’s still passive).
It is possible to avoid this situation by observing the actual state of the PMON process on my peer machine. In this example we are observing the actual peer state within a CTRL –Script. If a shutdown mode on the peer is detected we trigger automatically an active/passive switch. This reduces the time where the system is in the described situation to almost 0 seconds.
Just add this script to a new CTRL-Script and start it on both sides in your Redu-project:
#uses "pmon.ctl"
#uses "hosts.ctl"
string gTcpFifo;
int gTcpFileDescriptor;
main()
{
string sProjUser = "";
string sProjPassword = "";
int iPmonPort;
string sHostname;
dyn_dyn_string ddsResultList;
bool errList;
int loopDelayTime = 1;
if(!isRedundant())
{
DebugTN("fastSwitchPmon.ctl, no redu project - do nothing");
return;
}
initHosts();
paCfgReadValue(getPath(CONFIG_REL_PATH) + "/config", "general", "pmonPort", iPmonPort);
if(iPmonPort == 0)
{
iPmonPort = 4999;
}
DebugFTN("fastSwitchDebug", "check pmon running on port: ", iPmonPort);
if(getHostname() == host1)
{
sHostname = host2;
}
if(getHostname() == host2)
{
sHostname = host1;
}
DebugFTN("fastSwitchDebug", "check pmon list on host: ", sHostname);
while(1)
{
errList = pmon_query(sProjUser+"#"+sProjPassword+"#MGRLIST:STATI", sHostname, iPmonPort, ddsResultList, 0,1);
if(dynlen(ddsResultList) == 0)
{
DebugFTN("fastSwitchDebug", "pmon not running on host: ", sHostname);
delay(loopDelayTime);
continue;
}
DebugFTN("fastSwitchDebug", "state of remote pmon on host: ", sHostname, ddsResultList[dynlen(ddsResultList)][1]);
//DebugTN(ddsResultList[dynlen(ddsResultList)][1]);
if(strpos( ddsResultList[dynlen(ddsResultList)][1], "SHUTDOWN_MODE") > 0)
{
if(getHostname() == host1)
{
DebugTN("fastSwitchPmon set host 1 to active");
dpSet("_ReduManager.Command.PreferredSet", 1, //trigger of active/passive switch
"_ReduManager_2.MyErrorStatus", 999); //set error status on remote host to avoid automatic switch
delay(5);
dpSet("_ReduManager.Command.ActiveAuto", true); //remove preferred Redu set
delay(90); //wait for shutdown
}
if(getHostname() == host2)
{
DebugTN("fastSwitchPmon set host 2 to active");
dpSet("_ReduManager_2.Command.PreferredSet", 1, //trigger of active/passive switch
"_ReduManager.MyErrorStatus", 999); //set error status on remote host to avoid automatic switch
delay(5);
dpSet("_ReduManager_2.Command.ActiveAuto", true); //remove preferred Redu set
delay(90); //wait for shutdown
}
ddsResultList[dynlen(ddsResultList)][1] = "RESET";
}
else
{
//DebugTN("do nothing");
}
delay(loopDelayTime);
}
}