As all other monitors MMMon now only manipulates the pending_status
of the monitor object during analysis and only in the end touches
the server status.
All monitors (but for MariaDBMon) now handle connection errors in
the same manner.
An exception is MMMon that modifies both the server status and the
monitor status. However, in fact, all other monitors do it the wrong
way and update the server status directly instead of only the monitor
status that then at the end of the loop should be copied to the server
status.
All monitors (but possible for MariaDBMon) now handle the
connecting to the server in the same way, that is, if the
connecting fails, then the status is updated and we return.
The configuring of the monitor instance is now performed in a
separate function. That is in preparation for the moving of the
start function to maxscale::MonitorInstance.
- All monitors (but MariaDBMon for the time being) inherit
from that.
- All common member variables moved to that class. Still
manipulated in derived classes.
In subsequent commits common functionality will be moved to
that class.
StartMonitor() now takes a MXS_MONITOR_INSTANCE and returns
true, if the monitor could be started and false otherwise.
So, the setup is such that in createInstance(), the instance
data is created and then using startMonitor() and stopMonitor()
the monitor is started/stopped. Finally in destroyInstance(),
the actual instance data is deleted.
The following type name changes
MXS_MONITOR_OBJECT -> MXS_MONITOR_API
MXS_SPECIFIC_MONITOR -> MXS_MONITOR_INSTANCE
Further, the 'handle' instance variable of what used to be
called MXS_MONITOR_OBJECT has been renamed to 'api'.
An example, what used to look like
mon->module->stopMonitor(mon->handle);
now looks like
mon->api->stopMonitor(mon->instance);
which makes it more obvious what is going on.
CreateInstance() (renamed from initMonitor()) and destroyInstance()
(renamed from finishMonitor()) have now tentatively been
implemented for all monitors.
Next step is to
1) change the prototype of startMonitor() to
bool (*startMonitor)(MXS_SPECIFIC_MONITOR*,
const MXS_MONITOR_PARAMETER*);
and assume that mon->handle will always contain the
instance,
2) not delete any data in stopMonitor(),
3) add monitorCreateAll() that calls createInstance() for all
monitors (and call that in main()), and
4) add monitorDestroyAll() that calls destroyInstance() for
all monitors (and call that in main()).
Now, all monitor functions but startMonitor takes a
MXS_SPECIFIC_MONITOR instead of MXS_MONITOR. That is, startMonitor
is now like a static factory member returning a new specific
monitor instance and the other functions are like member functions
of that instance.
Instead of using void there's now a MXS_SPECIFIC_MONITOR struct
from which monitor specific types can be derived. This change
does not bring about other benefits than a bit of clarity but
this is the first step in clearing up the monitor API.
It is now possible to specify the thread stack size to be used,
when a new thread is created. This will subsequently be used
for allowing the stack size to be specified for worker threads.
All monitors now persist the state of the server in a monitor journal
file.
Moved the removal of stale journals into the core and removed them from
the monitor journal interface.
If a monitor is started and stopped before the external monitoring thread
has had time to start, a deadlock will occur.
The first thing that the monitoring threads do is read the monitor handle
from the monitor object. This handle is given as the return value of
startMonitor and it is stored in the monitor object. As this can still be
NULL when the monitor thread starts, the threads use locks to prevent
this.
The correct way to prevent this is to pass the handle as the thread
parameter so that no locks are required.