Some prep work for shared datastores, removed datastoreprovider
This commit is contained in:
@@ -3,9 +3,9 @@ using System;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Discord.Data
|
namespace Discord
|
||||||
{
|
{
|
||||||
public class DefaultDataStore : DataStore
|
public class DataStore
|
||||||
{
|
{
|
||||||
private const int CollectionConcurrencyLevel = 1; //WebSocket updater/event handler. //TODO: Needs profiling, increase to 2?
|
private const int CollectionConcurrencyLevel = 1; //WebSocket updater/event handler. //TODO: Needs profiling, increase to 2?
|
||||||
private const double AverageChannelsPerGuild = 10.22; //Source: Googie2149
|
private const double AverageChannelsPerGuild = 10.22; //Source: Googie2149
|
||||||
@@ -17,12 +17,12 @@ namespace Discord.Data
|
|||||||
private readonly ConcurrentDictionary<ulong, CachedGuild> _guilds;
|
private readonly ConcurrentDictionary<ulong, CachedGuild> _guilds;
|
||||||
private readonly ConcurrentDictionary<ulong, CachedGlobalUser> _users;
|
private readonly ConcurrentDictionary<ulong, CachedGlobalUser> _users;
|
||||||
|
|
||||||
internal override IReadOnlyCollection<ICachedChannel> Channels => _channels.ToReadOnlyCollection();
|
internal IReadOnlyCollection<ICachedChannel> Channels => _channels.ToReadOnlyCollection();
|
||||||
internal override IReadOnlyCollection<CachedDMChannel> DMChannels => _dmChannels.ToReadOnlyCollection();
|
internal IReadOnlyCollection<CachedDMChannel> DMChannels => _dmChannels.ToReadOnlyCollection();
|
||||||
internal override IReadOnlyCollection<CachedGuild> Guilds => _guilds.ToReadOnlyCollection();
|
internal IReadOnlyCollection<CachedGuild> Guilds => _guilds.ToReadOnlyCollection();
|
||||||
internal override IReadOnlyCollection<CachedGlobalUser> Users => _users.ToReadOnlyCollection();
|
internal IReadOnlyCollection<CachedGlobalUser> Users => _users.ToReadOnlyCollection();
|
||||||
|
|
||||||
public DefaultDataStore(int guildCount, int dmChannelCount)
|
public DataStore(int guildCount, int dmChannelCount)
|
||||||
{
|
{
|
||||||
double estimatedChannelCount = guildCount * AverageChannelsPerGuild + dmChannelCount;
|
double estimatedChannelCount = guildCount * AverageChannelsPerGuild + dmChannelCount;
|
||||||
double estimatedUsersCount = guildCount * AverageUsersPerGuild;
|
double estimatedUsersCount = guildCount * AverageUsersPerGuild;
|
||||||
@@ -32,18 +32,18 @@ namespace Discord.Data
|
|||||||
_users = new ConcurrentDictionary<ulong, CachedGlobalUser>(CollectionConcurrencyLevel, (int)(estimatedUsersCount * CollectionMultiplier));
|
_users = new ConcurrentDictionary<ulong, CachedGlobalUser>(CollectionConcurrencyLevel, (int)(estimatedUsersCount * CollectionMultiplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override ICachedChannel GetChannel(ulong id)
|
internal ICachedChannel GetChannel(ulong id)
|
||||||
{
|
{
|
||||||
ICachedChannel channel;
|
ICachedChannel channel;
|
||||||
if (_channels.TryGetValue(id, out channel))
|
if (_channels.TryGetValue(id, out channel))
|
||||||
return channel;
|
return channel;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
internal override void AddChannel(ICachedChannel channel)
|
internal void AddChannel(ICachedChannel channel)
|
||||||
{
|
{
|
||||||
_channels[channel.Id] = channel;
|
_channels[channel.Id] = channel;
|
||||||
}
|
}
|
||||||
internal override ICachedChannel RemoveChannel(ulong id)
|
internal ICachedChannel RemoveChannel(ulong id)
|
||||||
{
|
{
|
||||||
ICachedChannel channel;
|
ICachedChannel channel;
|
||||||
if (_channels.TryRemove(id, out channel))
|
if (_channels.TryRemove(id, out channel))
|
||||||
@@ -51,19 +51,19 @@ namespace Discord.Data
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override CachedDMChannel GetDMChannel(ulong userId)
|
internal CachedDMChannel GetDMChannel(ulong userId)
|
||||||
{
|
{
|
||||||
CachedDMChannel channel;
|
CachedDMChannel channel;
|
||||||
if (_dmChannels.TryGetValue(userId, out channel))
|
if (_dmChannels.TryGetValue(userId, out channel))
|
||||||
return channel;
|
return channel;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
internal override void AddDMChannel(CachedDMChannel channel)
|
internal void AddDMChannel(CachedDMChannel channel)
|
||||||
{
|
{
|
||||||
_channels[channel.Id] = channel;
|
_channels[channel.Id] = channel;
|
||||||
_dmChannels[channel.Recipient.Id] = channel;
|
_dmChannels[channel.Recipient.Id] = channel;
|
||||||
}
|
}
|
||||||
internal override CachedDMChannel RemoveDMChannel(ulong userId)
|
internal CachedDMChannel RemoveDMChannel(ulong userId)
|
||||||
{
|
{
|
||||||
CachedDMChannel channel;
|
CachedDMChannel channel;
|
||||||
ICachedChannel ignored;
|
ICachedChannel ignored;
|
||||||
@@ -75,18 +75,18 @@ namespace Discord.Data
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override CachedGuild GetGuild(ulong id)
|
internal CachedGuild GetGuild(ulong id)
|
||||||
{
|
{
|
||||||
CachedGuild guild;
|
CachedGuild guild;
|
||||||
if (_guilds.TryGetValue(id, out guild))
|
if (_guilds.TryGetValue(id, out guild))
|
||||||
return guild;
|
return guild;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
internal override void AddGuild(CachedGuild guild)
|
internal void AddGuild(CachedGuild guild)
|
||||||
{
|
{
|
||||||
_guilds[guild.Id] = guild;
|
_guilds[guild.Id] = guild;
|
||||||
}
|
}
|
||||||
internal override CachedGuild RemoveGuild(ulong id)
|
internal CachedGuild RemoveGuild(ulong id)
|
||||||
{
|
{
|
||||||
CachedGuild guild;
|
CachedGuild guild;
|
||||||
if (_guilds.TryRemove(id, out guild))
|
if (_guilds.TryRemove(id, out guild))
|
||||||
@@ -94,18 +94,18 @@ namespace Discord.Data
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override CachedGlobalUser GetUser(ulong id)
|
internal CachedGlobalUser GetUser(ulong id)
|
||||||
{
|
{
|
||||||
CachedGlobalUser user;
|
CachedGlobalUser user;
|
||||||
if (_users.TryGetValue(id, out user))
|
if (_users.TryGetValue(id, out user))
|
||||||
return user;
|
return user;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
internal override CachedGlobalUser GetOrAddUser(ulong id, Func<ulong, CachedGlobalUser> userFactory)
|
internal CachedGlobalUser GetOrAddUser(ulong id, Func<ulong, CachedGlobalUser> userFactory)
|
||||||
{
|
{
|
||||||
return _users.GetOrAdd(id, userFactory);
|
return _users.GetOrAdd(id, userFactory);
|
||||||
}
|
}
|
||||||
internal override CachedGlobalUser RemoveUser(ulong id)
|
internal CachedGlobalUser RemoveUser(ulong id)
|
||||||
{
|
{
|
||||||
CachedGlobalUser user;
|
CachedGlobalUser user;
|
||||||
if (_users.TryRemove(id, out user))
|
if (_users.TryRemove(id, out user))
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
namespace Discord.Data
|
|
||||||
{
|
|
||||||
public delegate DataStore DataStoreProvider(int shardId, int totalShards, int guildCount, int dmCount);
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Discord.Data
|
|
||||||
{
|
|
||||||
public abstract class DataStore
|
|
||||||
{
|
|
||||||
internal abstract IReadOnlyCollection<ICachedChannel> Channels { get; }
|
|
||||||
internal abstract IReadOnlyCollection<CachedDMChannel> DMChannels { get; }
|
|
||||||
internal abstract IReadOnlyCollection<CachedGuild> Guilds { get; }
|
|
||||||
internal abstract IReadOnlyCollection<CachedGlobalUser> Users { get; }
|
|
||||||
|
|
||||||
internal abstract ICachedChannel GetChannel(ulong id);
|
|
||||||
internal abstract void AddChannel(ICachedChannel channel);
|
|
||||||
internal abstract ICachedChannel RemoveChannel(ulong id);
|
|
||||||
|
|
||||||
internal abstract CachedDMChannel GetDMChannel(ulong userId);
|
|
||||||
internal abstract void AddDMChannel(CachedDMChannel channel);
|
|
||||||
internal abstract CachedDMChannel RemoveDMChannel(ulong userId);
|
|
||||||
|
|
||||||
internal abstract CachedGuild GetGuild(ulong id);
|
|
||||||
internal abstract void AddGuild(CachedGuild guild);
|
|
||||||
internal abstract CachedGuild RemoveGuild(ulong id);
|
|
||||||
|
|
||||||
internal abstract CachedGlobalUser GetUser(ulong id);
|
|
||||||
internal abstract CachedGlobalUser GetOrAddUser(ulong userId, Func<ulong, CachedGlobalUser> userFactory);
|
|
||||||
internal abstract CachedGlobalUser RemoveUser(ulong id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace Discord.Data
|
|
||||||
{
|
|
||||||
//TODO: Implement
|
|
||||||
//TODO: CachedPublicUser's GuildCount system is not at all multi-writer threadsafe!
|
|
||||||
//TODO: CachedPublicUser's Update method is not multi-writer threadsafe!
|
|
||||||
//TODO: Are there other multiwriters across shards?
|
|
||||||
|
|
||||||
/*public class SharedDataStore
|
|
||||||
{
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Discord.API.Gateway;
|
using Discord.API.Gateway;
|
||||||
using Discord.Data;
|
|
||||||
using Discord.Extensions;
|
using Discord.Extensions;
|
||||||
using Discord.Logging;
|
using Discord.Logging;
|
||||||
using Discord.Net.Converters;
|
using Discord.Net.Converters;
|
||||||
@@ -26,7 +25,6 @@ namespace Discord
|
|||||||
#if BENCHMARK
|
#if BENCHMARK
|
||||||
private readonly Logger _benchmarkLogger;
|
private readonly Logger _benchmarkLogger;
|
||||||
#endif
|
#endif
|
||||||
private readonly DataStoreProvider _dataStoreProvider;
|
|
||||||
private readonly JsonSerializer _serializer;
|
private readonly JsonSerializer _serializer;
|
||||||
private readonly int _connectionTimeout, _reconnectDelay, _failedReconnectDelay;
|
private readonly int _connectionTimeout, _reconnectDelay, _failedReconnectDelay;
|
||||||
private readonly int _largeThreshold;
|
private readonly int _largeThreshold;
|
||||||
@@ -71,7 +69,6 @@ namespace Discord
|
|||||||
_connectionTimeout = config.ConnectionTimeout;
|
_connectionTimeout = config.ConnectionTimeout;
|
||||||
_reconnectDelay = config.ReconnectDelay;
|
_reconnectDelay = config.ReconnectDelay;
|
||||||
_failedReconnectDelay = config.FailedReconnectDelay;
|
_failedReconnectDelay = config.FailedReconnectDelay;
|
||||||
_dataStoreProvider = config.DataStoreProvider;
|
|
||||||
|
|
||||||
MessageCacheSize = config.MessageCacheSize;
|
MessageCacheSize = config.MessageCacheSize;
|
||||||
_largeThreshold = config.LargeThreshold;
|
_largeThreshold = config.LargeThreshold;
|
||||||
@@ -481,7 +478,7 @@ namespace Discord
|
|||||||
await _gatewayLogger.DebugAsync("Received Dispatch (READY)").ConfigureAwait(false);
|
await _gatewayLogger.DebugAsync("Received Dispatch (READY)").ConfigureAwait(false);
|
||||||
|
|
||||||
var data = (payload as JToken).ToObject<ReadyEvent>(_serializer);
|
var data = (payload as JToken).ToObject<ReadyEvent>(_serializer);
|
||||||
var dataStore = _dataStoreProvider(ShardId, _totalShards, data.Guilds.Length, data.PrivateChannels.Length);
|
var dataStore = new DataStore( data.Guilds.Length, data.PrivateChannels.Length);
|
||||||
|
|
||||||
var currentUser = new CachedSelfUser(this, data.User);
|
var currentUser = new CachedSelfUser(this, data.User);
|
||||||
int unavailableGuilds = 0;
|
int unavailableGuilds = 0;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Discord.Data;
|
using Discord.Net.WebSockets;
|
||||||
using Discord.Net.WebSockets;
|
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
@@ -29,11 +28,7 @@ namespace Discord
|
|||||||
/// Decreasing this may reduce CPU usage while increasing login time and network usage.
|
/// Decreasing this may reduce CPU usage while increasing login time and network usage.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int LargeThreshold { get; set; } = 250;
|
public int LargeThreshold { get; set; } = 250;
|
||||||
|
|
||||||
//Engines
|
|
||||||
|
|
||||||
/// <summary> Gets or sets the provider used to generate datastores. </summary>
|
|
||||||
public DataStoreProvider DataStoreProvider { get; set; } = (shardId, totalShards, guildCount, dmCount) => new DefaultDataStore(guildCount, dmCount);
|
|
||||||
/// <summary> Gets or sets the provider used to generate new websocket connections. </summary>
|
/// <summary> Gets or sets the provider used to generate new websocket connections. </summary>
|
||||||
public WebSocketProvider WebSocketProvider { get; set; } = () => new DefaultWebSocketClient();
|
public WebSocketProvider WebSocketProvider { get; set; } = () => new DefaultWebSocketClient();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Discord.API;
|
||||||
using Model = Discord.API.User;
|
using Model = Discord.API.User;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
@@ -33,6 +34,12 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Update(Model model, UpdateSource source)
|
||||||
|
{
|
||||||
|
lock (this)
|
||||||
|
base.Update(model, source);
|
||||||
|
}
|
||||||
|
|
||||||
public CachedGlobalUser Clone() => MemberwiseClone() as CachedGlobalUser;
|
public CachedGlobalUser Clone() => MemberwiseClone() as CachedGlobalUser;
|
||||||
ICachedUser ICachedUser.Clone() => Clone();
|
ICachedUser ICachedUser.Clone() => Clone();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Discord.Data;
|
using Discord.Extensions;
|
||||||
using Discord.Extensions;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
Reference in New Issue
Block a user