Commit 2d6ecf3c authored by chiaming2000's avatar chiaming2000
Browse files

Minor improvement for the heartbeat example - added sweep feature to

remove internal heartbeat entries for those heartbeat entries not
updated for more than two minutes.  The sweep is on demand only - action
performed only when a new request is received.  
parent 73036f19
Loading
Loading
Loading
Loading
+48 −9
Original line number Diff line number Diff line
@@ -21,16 +21,14 @@ package com.seagate.kinetic.example.heartbeat.rest;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;

import java.util.SortedMap;
import java.util.TreeMap;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.gson.Gson;

import com.google.gson.stream.JsonReader;
import com.seagate.kinetic.heartbeat.HeartbeatMessage;
import com.seagate.kinetic.monitor.HeartbeatListener;
@@ -52,8 +50,12 @@ public class HeartbeatCollector extends HeartbeatListener {
    private final static Logger logger = Logger
            .getLogger(HeartbeatCollector.class.getName());
    
    private SortedMap <String, HeartbeatMessage> drives = 
            Collections.synchronizedSortedMap(new TreeMap<String, HeartbeatMessage>());
    private static long SWEEP_TIME = 120000;
    
    private SortedMap <String, MessageContainer> drives = 
            Collections.synchronizedSortedMap(new TreeMap<String, MessageContainer>());
    
    private long lastSweepTime = System.currentTimeMillis();

    public HeartbeatCollector() throws IOException {
        super();
@@ -76,7 +78,11 @@ public class HeartbeatCollector extends HeartbeatListener {
            
            String key = hbm.getNetworkInterfaces().get(0).getIpV4Address() + ":" + hbm.getPort();
            
            this.drives.put(key, hbm);
            MessageContainer container = new MessageContainer (hbm, System.currentTimeMillis());
            
            
            this.drives.put(key, container);
            
            
            logger.fine ("received heart beat: " + key);
            
@@ -92,8 +98,41 @@ public class HeartbeatCollector extends HeartbeatListener {
     * 
     * @return the heart beat map used by this collector
     */
    public SortedMap<String, HeartbeatMessage> getHeartBeatMap() {
        return new TreeMap<String, HeartbeatMessage> (drives);
    public SortedMap<String, MessageContainer> getHeartBeatMap() {

        // do a bit of clean up
        sweep();

        return new TreeMap<String, MessageContainer>(drives);
    }
    
    /**
     * clean up heartbeat table
     */
    private void sweep() {
        
        long now = System.currentTimeMillis();
        
        synchronized (this) {
            if ((now - this.lastSweepTime) >= SWEEP_TIME) {

                ArrayList<String> keys = new ArrayList<String>();

                // do sweep
                for (String key : drives.keySet()) {
                    if ((now - drives.get(key).getTimestamp()) >= SWEEP_TIME) {
                        keys.add(key);
                    }
                }

                for (String key : keys) {
                    drives.remove(key);
                }

                this.lastSweepTime = now;
            }
        }
        
    }

}
+6 −4
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public class HeartbeatHandler extends AbstractHandler {
        
        response.getWriter().println("<br>update time: " + new Date() + "</br>");
        
        SortedMap <String, HeartbeatMessage> map = hbc.getHeartBeatMap();
        SortedMap <String, MessageContainer> map = hbc.getHeartBeatMap();
        
       int index = 0;
       
@@ -79,6 +79,7 @@ public class HeartbeatHandler extends AbstractHandler {
       response.getWriter().println("<td>IP Address</td>");
       response.getWriter().println("<td>TCP Port</td>");
       response.getWriter().println("<td>TLS Port</td>");
       response.getWriter().println("<td>Timestamp</td>");
       response.getWriter().println("</tr>");
       
        synchronized (this) {
@@ -87,9 +88,10 @@ public class HeartbeatHandler extends AbstractHandler {
                //response.getWriter().println("<br>" + index + ":    " + key);
                response.getWriter().println("<tr>");
                response.getWriter().println("<td>" + index +"</td>");
                response.getWriter().println("<td>" + map.get(key).getNetworkInterfaces().get(0).getIpV4Address() +"</td>");
                response.getWriter().println("<td>" + map.get(key).getPort() +"</td>");
                response.getWriter().println("<td>" + map.get(key).getTlsPort() +"</td>");
                response.getWriter().println("<td>" + map.get(key).getHeartbeatMessage().getNetworkInterfaces().get(0).getIpV4Address() +"</td>");
                response.getWriter().println("<td>" + map.get(key).getHeartbeatMessage().getPort() +"</td>");
                response.getWriter().println("<td>" + map.get(key).getHeartbeatMessage().getTlsPort() +"</td>");
                response.getWriter().println("<td>" + new Date (map.get(key).getTimestamp()) +"</td>");
                response.getWriter().println("</tr>");
                index ++;
            }
+49 −0
Original line number Diff line number Diff line
/**
 * 
 * Copyright (C) 2014 Seagate Technology.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */
package com.seagate.kinetic.example.heartbeat.rest;

import com.seagate.kinetic.heartbeat.HeartbeatMessage;

/**
 * 
 * Container to hold heartbeat message and the timestamp put in the heartbeat table.
 * 
 * @author chiaming
 *
 */
public class MessageContainer {
    
    private HeartbeatMessage hbm = null;
    
    private long timestamp = 0;

    public MessageContainer(HeartbeatMessage hbm, long timestamp) {
        this.hbm = hbm;
        this.timestamp = timestamp;
    }
    
    public HeartbeatMessage getHeartbeatMessage() {
        return this.hbm;
    }
    
    public long getTimestamp() {
        return this.timestamp;
    }
}