public void initialize()

in src/main/java/org/apache/sling/discovery/impl/common/heartbeat/HeartbeatHandler.java [213:286]


    public void initialize(final DiscoveryServiceImpl discoveryService,
            final String initialVotingId) {
        synchronized(lock) {
            this.discoveryServiceImpl = discoveryService;
        	this.nextVotingId = initialVotingId;
        	logger.info("initialize: nextVotingId="+nextVotingId);
            issueHeartbeat();
        }

        try {
            long interval = config.getHeartbeatInterval();
            logger.info("initialize: starting periodic heartbeat job for "+slingId+" with interval "+interval+" sec.");
            if (interval==0) {
                logger.warn("initialize: Repeat interval cannot be zero. Defaulting to 10sec");
                interval = 10;
            }
            periodicPingJob = new PeriodicBackgroundJob(interval, NAME, this);
        } catch (Exception e) {
            logger.error("activate: Could not start heartbeat runner: " + e, e);
        }

        // SLING-5195 - to account for repository delays, the writing of heartbeats and voting
        // should be done independently of getting the current clusterView and
        // potentially sending a topology event.
        // so this second part is now done (additionally) in a 2nd runner here:
        try {
            long interval = config.getHeartbeatInterval();
            final long heartbeatTimeoutMillis = config.getHeartbeatTimeoutMillis();
            final long heartbeatIntervalMillis = config.getHeartbeatInterval() * 1000;
            final long maxMillisSinceHb = Math.max(Math.min(heartbeatTimeoutMillis, 2 * heartbeatIntervalMillis),
                    heartbeatTimeoutMillis - 2 * heartbeatIntervalMillis);
            logger.info("initialize: starting periodic checkForLocalClusterViewChange job for "+slingId+" with maxMillisSinceHb=" + maxMillisSinceHb + "ms, interval="+interval+" sec.");
            if (interval==0) {
                logger.warn("initialize: Repeat interval cannot be zero. Defaulting to 10sec.");
                interval = 10;
            }
            periodicCheckJob = new PeriodicBackgroundJob(interval, NAME+".checkForLocalClusterViewChange", new Runnable() {

                @Override
                public void run() {
                    Calendar lastHb = lastHeartbeatWritten;
                    if (lastHb!=null) {
                        // check to see when we last wrote a heartbeat
                        // if it is older than the configured timeout,
                        // then mark ourselves as in topologyChanging automatically
                        final long timeSinceHb = System.currentTimeMillis() - lastHb.getTimeInMillis();
                        // SLING-5285: add a safety-margin for SLING-5195
                        if (timeSinceHb > maxMillisSinceHb) {
                            logger.warn("checkForLocalClusterViewChange/.run: time since local instance last wrote a heartbeat is " + timeSinceHb + "ms"
                                    + " (heartbeatTimeoutMillis=" + heartbeatTimeoutMillis + ", heartbeatIntervalMillis=" + heartbeatIntervalMillis
                                    + " => maxMillisSinceHb=" + maxMillisSinceHb + "). Flagging us as (still) changing");
                            // mark the current establishedView as faulty
                            invalidateCurrentEstablishedView();

                            // then tell the listeners immediately
                            // note that just calling handleTopologyChanging alone - without the above invalidate -
                            // won't be sufficient, because that would only affect the listeners, not the
                            // getTopology() call.
                            discoveryService.handleTopologyChanging();
                            return;
                        }
                    }
                    // SLING-5195: guarantee frequent calls to checkForLocalClusterViewChange,
                    // independently of blocked write/save operations
                    logger.debug("checkForLocalClusterViewChange/.run: going to check for topology change...");
                    discoveryService.checkForLocalClusterViewChange();
                    logger.debug("checkForLocalClusterViewChange/.run: check for topology change done.");
                }

            });
        } catch (Exception e) {
            logger.error("activate: Could not start heartbeat runner: " + e, e);
        }
    }