Make cache an option, for issue #25
This commit is contained in:
@@ -44,6 +44,10 @@ namespace OpenSim.Services.PresenceService
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected bool m_allowDuplicatePresences = false;
|
||||
protected bool m_useCache = true;
|
||||
const int EXPIREMS = 300000;
|
||||
static ExpiringCacheOS<UUID, PresenceData> BySessionCache = new ExpiringCacheOS<UUID, PresenceData>(60000);
|
||||
static ExpiringCacheOS<string, PresenceData> ByUserCache = new ExpiringCacheOS<string, PresenceData>(60000);
|
||||
|
||||
public PresenceService(IConfigSource config)
|
||||
: base(config)
|
||||
@@ -54,15 +58,37 @@ namespace OpenSim.Services.PresenceService
|
||||
if (presenceConfig != null)
|
||||
{
|
||||
m_allowDuplicatePresences = presenceConfig.GetBoolean("AllowDuplicatePresences", m_allowDuplicatePresences);
|
||||
m_useCache = presenceConfig.GetBoolean("UseCache", m_useCache);
|
||||
}
|
||||
}
|
||||
|
||||
public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
|
||||
{
|
||||
PresenceData prevUser = GetUser(userID);
|
||||
bool inCache = false;
|
||||
PresenceData prevUser;
|
||||
|
||||
if (m_useCache)
|
||||
{
|
||||
inCache = ByUserCache.TryGetValue(userID, out prevUser);
|
||||
if (!inCache)
|
||||
{
|
||||
PresenceData[] dataprv = m_Database.Get("UserID", userID);
|
||||
if (dataprv.Length > 0)
|
||||
prevUser = dataprv[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
prevUser = GetUser(userID);
|
||||
|
||||
if (!m_allowDuplicatePresences && (prevUser != null))
|
||||
{
|
||||
m_Database.Delete("UserID", userID.ToString());
|
||||
if(m_useCache && inCache)
|
||||
{
|
||||
BySessionCache.Remove(prevUser.SessionID);
|
||||
ByUserCache.Remove(userID);
|
||||
}
|
||||
}
|
||||
|
||||
PresenceData data = new PresenceData();
|
||||
|
||||
@@ -73,6 +99,11 @@ namespace OpenSim.Services.PresenceService
|
||||
data.Data["SecureSessionID"] = secureSessionID.ToString();
|
||||
|
||||
m_Database.Store(data);
|
||||
if (m_useCache)
|
||||
{
|
||||
BySessionCache.Add(sessionID, data, EXPIREMS);
|
||||
ByUserCache.Add(userID, data, EXPIREMS);
|
||||
}
|
||||
|
||||
string prevUserStr = "";
|
||||
if (prevUser != null)
|
||||
@@ -86,14 +117,31 @@ namespace OpenSim.Services.PresenceService
|
||||
|
||||
public bool LogoutAgent(UUID sessionID)
|
||||
{
|
||||
PresenceInfo presence = GetAgent(sessionID);
|
||||
bool inCache = false;
|
||||
PresenceData presence;
|
||||
|
||||
if (m_useCache)
|
||||
{
|
||||
inCache = BySessionCache.TryGetValue(sessionID, out presence);
|
||||
if(!inCache)
|
||||
presence = m_Database.Get(sessionID);
|
||||
}
|
||||
else
|
||||
presence = m_Database.Get(sessionID);
|
||||
|
||||
m_log.DebugFormat("[PRESENCE SERVICE]: LogoutAgent: session {0}, user {1}, region {2}",
|
||||
sessionID,
|
||||
(presence == null) ? null : presence.UserID,
|
||||
(presence == null) ? null : presence.RegionID.ToString());
|
||||
|
||||
return m_Database.Delete("SessionID", sessionID.ToString());
|
||||
bool ret = m_Database.Delete("SessionID", sessionID.ToString());
|
||||
if(m_useCache && inCache)
|
||||
{
|
||||
BySessionCache.Remove(sessionID);
|
||||
if(presence is not null)
|
||||
ByUserCache.Remove(presence.UserID);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool LogoutRegionAgents(UUID regionID)
|
||||
@@ -103,8 +151,16 @@ namespace OpenSim.Services.PresenceService
|
||||
if ((prevSessions is null) || (prevSessions.Length == 0))
|
||||
return true;
|
||||
|
||||
m_log.DebugFormat("[PRESENCE SERVICE]: Logout users in region {0}: {1}", regionID,
|
||||
string.Join(", ", Array.ConvertAll(prevSessions, session => session.UserID)));
|
||||
m_log.DebugFormat("[PRESENCE SERVICE]: Logout users in region {0}", regionID);
|
||||
if (m_useCache)
|
||||
{
|
||||
for (int i = 0; i < prevSessions.Length; ++i)
|
||||
{
|
||||
PresenceData pd = prevSessions[i];
|
||||
BySessionCache.Remove(pd.SessionID);
|
||||
ByUserCache.Remove(pd.UserID);
|
||||
}
|
||||
}
|
||||
|
||||
// There's a small chance that LogoutRegionAgents() will logout different users than the
|
||||
// list that was logged above, but it's unlikely and not worth dealing with.
|
||||
@@ -118,7 +174,17 @@ namespace OpenSim.Services.PresenceService
|
||||
{
|
||||
try
|
||||
{
|
||||
PresenceData presence = m_Database.Get(sessionID);
|
||||
bool inCache = false;
|
||||
PresenceData presence;
|
||||
|
||||
if (m_useCache)
|
||||
{
|
||||
inCache = BySessionCache.TryGetValue(sessionID, out presence);
|
||||
if(!inCache)
|
||||
presence = m_Database.Get(sessionID);
|
||||
}
|
||||
else
|
||||
presence = m_Database.Get(sessionID);
|
||||
|
||||
bool success;
|
||||
if (presence == null)
|
||||
@@ -131,6 +197,21 @@ namespace OpenSim.Services.PresenceService
|
||||
sessionID, (presence == null) ? null : presence.UserID, regionID,
|
||||
(presence == null) ? "not logged-in" : "region " + presence.RegionID);
|
||||
|
||||
if (m_useCache)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
presence.RegionID = regionID;
|
||||
BySessionCache.Add(sessionID, presence, EXPIREMS); // lastseen seems unused
|
||||
ByUserCache.Add(presence.UserID, presence, EXPIREMS); // lastseen seems unused
|
||||
}
|
||||
else if (inCache)
|
||||
{
|
||||
BySessionCache.Remove(sessionID);
|
||||
ByUserCache.Remove(presence.UserID);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -142,37 +223,72 @@ namespace OpenSim.Services.PresenceService
|
||||
|
||||
public PresenceInfo GetAgent(UUID sessionID)
|
||||
{
|
||||
PresenceInfo ret = new PresenceInfo();
|
||||
PresenceData data;
|
||||
|
||||
if (m_useCache)
|
||||
{
|
||||
if(!BySessionCache.TryGetValue(sessionID, out data))
|
||||
data = m_Database.Get(sessionID);
|
||||
}
|
||||
else
|
||||
data = m_Database.Get(sessionID);
|
||||
|
||||
PresenceData data = m_Database.Get(sessionID);
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
ret.UserID = data.UserID;
|
||||
ret.RegionID = data.RegionID;
|
||||
if (m_useCache)
|
||||
{
|
||||
BySessionCache.Add(sessionID, data, EXPIREMS);
|
||||
ByUserCache.Add(data.UserID, data, EXPIREMS);
|
||||
}
|
||||
|
||||
var ret = new PresenceInfo()
|
||||
{
|
||||
UserID = data.UserID,
|
||||
RegionID = data.RegionID
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
public PresenceInfo[] GetAgents(string[] userIDs)
|
||||
{
|
||||
List<PresenceInfo> info = new List<PresenceInfo>();
|
||||
|
||||
var info = new List<PresenceInfo>(userIDs.Length);
|
||||
PresenceInfo ret;
|
||||
foreach (string userIDStr in userIDs)
|
||||
{
|
||||
PresenceData[] data = m_Database.Get("UserID", userIDStr);
|
||||
|
||||
foreach (PresenceData d in data)
|
||||
if(m_useCache && ByUserCache.TryGetValue(userIDStr, out PresenceData pd))
|
||||
{
|
||||
PresenceInfo ret = new PresenceInfo();
|
||||
|
||||
ret.UserID = d.UserID;
|
||||
ret.RegionID = d.RegionID;
|
||||
|
||||
// cache hit
|
||||
ByUserCache.Add(pd.UserID, pd, EXPIREMS);
|
||||
BySessionCache.Add(pd.SessionID, pd, EXPIREMS);
|
||||
ret = new PresenceInfo()
|
||||
{
|
||||
UserID = pd.UserID,
|
||||
RegionID = pd.RegionID
|
||||
};
|
||||
info.Add(ret);
|
||||
}
|
||||
// m_log.DebugFormat(
|
||||
// "[PRESENCE SERVICE]: GetAgents for {0} found {1} presences", userIDStr, data.Length);
|
||||
else
|
||||
{
|
||||
// no cache used or cache miss
|
||||
PresenceData[] data = m_Database.Get("UserID", userIDStr);
|
||||
if(data.Length == 0)
|
||||
continue;
|
||||
PresenceData d = data[0];
|
||||
if (m_useCache)
|
||||
{
|
||||
ByUserCache.Add(d.UserID, d, EXPIREMS);
|
||||
BySessionCache.Add(d.SessionID, d, EXPIREMS);
|
||||
}
|
||||
ret = new PresenceInfo()
|
||||
{
|
||||
UserID = d.UserID,
|
||||
RegionID = d.RegionID
|
||||
};
|
||||
info.Add(ret);
|
||||
}
|
||||
//m_log.DebugFormat(
|
||||
// "[PRESENCE SERVICE]: GetAgents for {0} found {1} presences", userIDStr, data.Length);
|
||||
}
|
||||
|
||||
return info.ToArray();
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace OpenSim.Services.UserAccountService
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static bool m_Initialized;
|
||||
protected bool m_useCache = true;
|
||||
|
||||
public GridUserService(IConfigSource config) : base(config)
|
||||
{
|
||||
@@ -69,6 +70,13 @@ namespace OpenSim.Services.UserAccountService
|
||||
"This number may not be accurate as a region may crash or not be cleanly shutdown and leave grid users shown as online\n."
|
||||
+ "For this reason, users online for more than 5 days are not currently counted",
|
||||
HandleShowGridUsersOnline);
|
||||
|
||||
IConfig griduserConfig = config.Configs["GridUserService"];
|
||||
if (griduserConfig != null)
|
||||
{
|
||||
m_useCache = griduserConfig.GetBoolean("UseCache", m_useCache);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,27 +134,49 @@ namespace OpenSim.Services.UserAccountService
|
||||
MainConsole.Instance.Output("Users online: {0}", onlineRecentlyCount);
|
||||
}
|
||||
|
||||
private static ExpiringCacheOS<string, GridUserData> cache = new ExpiringCacheOS<string, GridUserData>(100000);
|
||||
private GridUserData GetGridUserData(string userID)
|
||||
{
|
||||
GridUserData d = null;
|
||||
if (userID.Length > 36) // it's a UUI
|
||||
{
|
||||
d = m_Database.Get(userID);
|
||||
}
|
||||
else // it's a UUID
|
||||
{
|
||||
GridUserData[] ds = m_Database.GetAll(userID);
|
||||
if (ds == null)
|
||||
return null;
|
||||
if (userID.Length > 36)
|
||||
userID = userID.Substring(0, 36);
|
||||
|
||||
if (ds.Length > 0)
|
||||
{
|
||||
d = ds[0];
|
||||
foreach (GridUserData dd in ds)
|
||||
if (dd.UserID.Length > d.UserID.Length) // find the longest
|
||||
d = dd;
|
||||
}
|
||||
if (m_useCache && cache.TryGetValue(userID, out GridUserData d))
|
||||
return d;
|
||||
|
||||
GridUserData[] ds = m_Database.GetAll(userID);
|
||||
if (ds == null || ds.Length == 0)
|
||||
{
|
||||
if (m_useCache) cache.Add(userID, null, 300000);
|
||||
return null;
|
||||
}
|
||||
|
||||
d = ds[0];
|
||||
if (ds.Length > 1)
|
||||
{
|
||||
// try find most recent record
|
||||
try
|
||||
{
|
||||
int tsta = int.Parse(d.Data["Login"]);
|
||||
int tstb = int.Parse(d.Data["Logout"]);
|
||||
int cur = tstb > tsta? tstb : tsta;
|
||||
|
||||
for (int i = 1; i < ds.Length; ++i)
|
||||
{
|
||||
GridUserData dd = ds[i];
|
||||
tsta = int.Parse(dd.Data["Login"]);
|
||||
tstb = int.Parse(dd.Data["Logout"]);
|
||||
if(tsta > tstb)
|
||||
tstb = tsta;
|
||||
if (tstb > cur)
|
||||
{
|
||||
cur = tstb;
|
||||
d = dd;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
if (m_useCache) cache.Add(userID, d, 300000);
|
||||
return d;
|
||||
}
|
||||
|
||||
@@ -227,6 +257,8 @@ namespace OpenSim.Services.UserAccountService
|
||||
d.Data["Login"] = Util.UnixTimeSinceEpoch().ToString();
|
||||
|
||||
m_Database.Store(d);
|
||||
if (m_useCache && userID.Length >= 36)
|
||||
cache.Add(userID.Substring(0, 36), d, 300000);
|
||||
|
||||
return ToInfo(d);
|
||||
}
|
||||
@@ -249,7 +281,13 @@ namespace OpenSim.Services.UserAccountService
|
||||
d.Data["LastPosition"] = lastPosition.ToString();
|
||||
d.Data["LastLookAt"] = lastLookAt.ToString();
|
||||
|
||||
return m_Database.Store(d);
|
||||
if(m_Database.Store(d))
|
||||
{
|
||||
if (m_useCache && userID.Length >= 36)
|
||||
cache.Add(userID.Substring(0, 36), d, 300000);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt)
|
||||
@@ -266,7 +304,13 @@ namespace OpenSim.Services.UserAccountService
|
||||
d.Data["HomePosition"] = homePosition.ToString();
|
||||
d.Data["HomeLookAt"] = homeLookAt.ToString();
|
||||
|
||||
return m_Database.Store(d);
|
||||
if(m_Database.Store(d))
|
||||
{
|
||||
if (m_useCache && userID.Length >= 36)
|
||||
cache.Add(userID.Substring(0, 36), d, 300000);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
||||
@@ -285,7 +329,13 @@ namespace OpenSim.Services.UserAccountService
|
||||
d.Data["LastPosition"] = lastPosition.ToString();
|
||||
d.Data["LastLookAt"] = lastLookAt.ToString();
|
||||
|
||||
return m_Database.Store(d);
|
||||
if(m_Database.Store(d))
|
||||
{
|
||||
if (m_useCache && userID.Length >= 36)
|
||||
cache.Add(userID.Substring(0, 36), d, 300000);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -490,6 +490,7 @@
|
||||
[GridUserService]
|
||||
; for the server connector
|
||||
LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService"
|
||||
;UseCache = true
|
||||
|
||||
|
||||
[AgentPreferencesService]
|
||||
@@ -500,6 +501,8 @@
|
||||
[PresenceService]
|
||||
; for the server connector
|
||||
LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService"
|
||||
;AllowDuplicatePresences = false
|
||||
;UseCache = true
|
||||
|
||||
[AvatarService]
|
||||
; for the server connector
|
||||
|
||||
@@ -431,6 +431,7 @@
|
||||
[GridUserService]
|
||||
; for the server connector
|
||||
LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService"
|
||||
;UseCache = true
|
||||
|
||||
|
||||
[AgentPreferencesService]
|
||||
@@ -441,6 +442,8 @@
|
||||
[PresenceService]
|
||||
; for the server connector
|
||||
LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService"
|
||||
;AllowDuplicatePresences = false
|
||||
;UseCache = true
|
||||
|
||||
[AvatarService]
|
||||
; for the server connector
|
||||
|
||||
Reference in New Issue
Block a user