public synchronized void unbind(EndOid oid, Ticket ticket) { List<Subscriber> subscribers = routes.get(oid); if (subscribers == null) { System.err.println("NULL Subscribers for: " + oid.toString()); return; } for (Subscriber sub : subscribers) { if (sub.ticket.equals(ticket)) { if (sub.continuation != null) { sub.continuation.resume(); sub.continuation = null; } subscribers.remove(sub); break; } } routes.put(oid, subscribers); if (subscribers.size() == 0) { Endpoint ep = registry.get(oid); if (ep == null) { System.err.println("Cannot find endpont: " + oid.toString()); return; } ep.idle = true; ep.idleTime = System.currentTimeMillis(); } }
protected synchronized void clean() { long now = System.currentTimeMillis(); // System.out.println("begin to clean: " + now); // clean subscribers Set<EndOid> keys = routes.keySet(); for (EndOid key : keys) { List<Subscriber> subscribers = routes.get(key); Iterator<Subscriber> it = subscribers.iterator(); while (it.hasNext()) { Subscriber sub = it.next(); if ((sub.continuation == null || sub.continuation.isExpired()) && ((sub.lastActive + 8000) < now)) { System.out.println("Clean NoTimeout Sub: " + sub); it.remove(); } else if ((sub.lastActive + 28000) < now) { System.out.println("Clean Timeout Sub: " + sub); // TODO: when continuation cannot be expired if (sub.continuation != null && sub.continuation.isSuspended()) { sub.continuation.resume(); sub.continuation = null; } it.remove(); } } if (subscribers.size() == 0) { Endpoint ep = registry.get(key); if (ep != null && !ep.idle) { ep.idle = true; ep.idleTime = System.currentTimeMillis(); } } routes.put(key, subscribers); } // clean endpoints Iterator<EndOid> keysIter = registry.keySet().iterator(); // for (EndOid key : keys) { while (keysIter.hasNext()) { EndOid key = keysIter.next(); Endpoint ep = registry.get(key); if (ep.idle && (ep.idleTime + 8000) < now) { // System.out.println("Clean Endpoint: " + key); // presence List<Buddy> buddies = roster.buddies(key); for (Buddy b : buddies) { Presence p = new Presence("offline", key, b.fid); p.setNick(ep.nick); p.setShow("unavailable"); p.setStatus(ep.status); // TODO: route(null, p); } // leave group presences for (EndOid grpOid : roster.groups(key)) { Presence p = new Presence("grpoffline", ep.endOid, grpOid); p.setNick(ep.nick); p.setShow("unavailable"); p.setStatus(grpOid.name); route(null, p); } // remove // registry.remove(key); keysIter.remove(); routes.remove(key); roster.clean(key); } } }