Mercurial Hosting > nabble
view src/nabble/view/web/user/OnlineStatus.java @ 62:4674ed7d56df default tip
remove n2
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sat, 30 Sep 2023 20:25:29 -0600 |
parents | 18cf4872fd7f |
children |
line wrap: on
line source
package nabble.view.web.user; import fschmidt.util.servlet.ServletUtils; import nabble.model.Executors; import nabble.model.ModelHome; import nabble.model.Site; import nabble.model.User; import nabble.view.lib.Jtp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; public class OnlineStatus { private static final Logger logger = LoggerFactory.getLogger(OnlineStatus.class); private static final long TIMEOUT = 3 * 60 * 1000L; // 3 minutes private static final String INVISIBLE = "invisible:"; /** Maps a site ID to a map (Person-Source-ID > last time) */ private static final Map<Long, Map<String, Long>> sitesMap = new HashMap<Long, Map<String, Long>>(); public static void setOnline(HttpServletRequest request, User user, Site site) { if( user==null ) return; String sourceId = user.getSearchId(); synchronized(sitesMap) { Map<String, Long> map = sitesMap.get(site.getId()); if (map == null) { map = new HashMap<String, Long>(); sitesMap.put(site.getId(), map); logger.debug("New map for site ID = " + site.getId()); } boolean isVisible = ServletUtils.getCookieValue(request, "visible") == null || !Jtp.isInteger(sourceId); map.put(isVisible? sourceId : INVISIBLE+sourceId, System.currentTimeMillis()); } } public static boolean isOnline(User visitor, Site site) { return isOnline(visitor.getSearchId(),site); } public static boolean isOnline(String sourceId, Site site) { synchronized(sitesMap) { Map<String, Long> map = sitesMap.get(site.getId()); return map != null && map.get(sourceId) != null; } } private static void runGC() { final long start = System.currentTimeMillis(); synchronized(sitesMap) { for( Iterator<Map<String, Long>> iter = sitesMap.values().iterator(); iter.hasNext(); ) { Map<String, Long> map = iter.next(); for( Iterator<Long> subIter = map.values().iterator(); subIter.hasNext(); ) { long time = subIter.next(); if (start - time > TIMEOUT) { subIter.remove(); logger.debug("Removed user"); } } if( map.isEmpty() ) { iter.remove(); logger.debug("Removed map"); } } } logger.info("OnlineStatus GC took " + (System.currentTimeMillis()-start) + " ms"); } public static String getOnlineStats() { int count = 0; int sites; float ratio = 0f; synchronized(sitesMap) { Collection<Map<String, Long>> entries = sitesMap.values(); for (Map<String, Long> entry : entries) { count += entry.keySet().size(); } sites = sitesMap.size(); if (sites > 0) ratio = count / (float) sitesMap.size(); } return "Users = " + count + " | Sites = " + sites + " | Ratio = " + String.format("%.2f", ratio); } public static Map<String, Integer> getOnlineSites() { Map<String, Integer> sites = new HashMap<String, Integer>(); synchronized(sitesMap) { for (Map.Entry<Long, Map<String, Long>> entry : sitesMap.entrySet()) { String url = ModelHome.getSite(entry.getKey()).getBaseUrl(); sites.put(url, entry.getValue().size()); } } return sites; } public static List<User> getOnlineUsers(Site site, boolean includeInvisibleUsers) { String[] visitorIDs = getVisitorIds(site); List<User> users = new ArrayList<User>(); for (String id : visitorIDs) { long userId = 0; if (Jtp.isInteger(id)) { userId = Long.valueOf(id); } else if (includeInvisibleUsers && isInvisible(id)) { userId = Long.valueOf(id.substring(INVISIBLE.length())); } if (userId > 0) { User u = site.getUser(userId); if (u != null) users.add(u); } } return users; } public static int getOnlineAnonymousUsersCount(Site site) { String[] visitorIDs = getVisitorIds(site); int c = 0; for (String id : visitorIDs) if (!Jtp.isInteger(id) && !isInvisible(id)) { c++; } return c; } public static int getOnlineInvisibleUsersCount(Site site) { String[] visitorIDs = getVisitorIds(site); int c = 0; for (String id : visitorIDs) { if (isInvisible(id)) c++; } return c; } private static String[] getVisitorIds(Site site) { synchronized(sitesMap) { Map<String, Long> map = sitesMap.get(site.getId()); if (map == null) return new String[0]; Set<String> set = map.keySet(); String[] visitorIds = new String[set.size()]; set.toArray(visitorIds); return visitorIds; } } private static boolean isInvisible(String id) { return id.startsWith(INVISIBLE); } static { Executors.scheduleWithFixedDelay(new Runnable(){ public void run(){ runGC(); } }, 2*60, 2*60, TimeUnit.SECONDS); // Every 2 minutes } }