Skip to content

Commit

Permalink
1.1.2 release; memory optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
haneytron committed Apr 19, 2014
1 parent 068415f commit a9a8969
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 62 deletions.
59 changes: 10 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SIMPLSOCKETS 1.1.1
SIMPLSOCKETS 1.1.2
===========


Expand All @@ -15,65 +15,26 @@ VERSION HISTORY
============================================


1.1.1
1.1.2
------------------

- Fixed a bug in SimplSocket regarding calculation of message length (thanks to Christoph Martens for identifying and reporting the bug)
- Optimizations to initial buffer allocations and sizes which result in a substantially smaller memory footprint

- Heuristics-based pool population (20% allocated initially instead of 100%, will grow as needed)

1.1.0
------------------


- Fixed multiple bugs in how SimplSocket class handled communication errors.

- Fixed bugs that could cause infinite client hang in the case that the server stopped responding.

- Fixed semaphore calculation bugs.

- Errors are now handled gracefully and correctly, with atomic exception raising via the passed in error handler event delegate.

- Slight performance improvements enabled by smoother connection error handling.

- Special thanks to Ruslan (https://github.com/ruzhovt) for discovering and documenting the source of these errors.


1.0.1
------------------


- Fixed logic error in BlockingQueue constructor where _queue wasn't actually assigned

- Fixed logic error in Pool where resetItemMethod was not always called when Popping an item

- Fixed atomicity of Error event so that it is raised exactly once on disconnection regardless of multithreaded use

- On error, communication methods now exit gracefully after Error event is raised (no bubbled exceptions)

- Exposed CurrentlyConnectedClients property on ISimplSocketServer

- Added XML comments to a few classes


1.0.0
------------------


- Initial release of SimplSockets

- Includes client and server methods
- 1/10 (or less) memory allocated for buffer collections when compared to previous versions.


INSTALLATION INSTRUCTIONS
============================================


Simply add the assembly to your project!
Just include the DLL in your project ([NuGet](http://www.nuget.org/packages/SimplSockets)) and then create the appropriate client or server object!

// To create a client
To create a client:

var client = SimplSocket.CreateClient(...)
`var client = SimplSocket.CreateClient(...)`

// To create a server
To create a server:

var server = SimplSocket.CreateServer(...)
`var server = SimplSocket.CreateServer(...)`
6 changes: 3 additions & 3 deletions SimplSockets/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyCompany("SimplSockets")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyCompany("Imperative Bytes, LLC")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTrademark("SimplSockets")]
Expand All @@ -20,4 +20,4 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.*")]
[assembly: AssemblyVersion("1.1.2.*")]
21 changes: 11 additions & 10 deletions SimplSockets/SimplSocket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ private SimplSocket(Func<Socket> socketFunc, EventHandler<SocketErrorArgs> error
_maxConnectionsSemaphore = new Semaphore(maximumConnections, maximumConnections);
_useNagleAlgorithm = useNagleAlgorithm;

_receiveBufferQueue = new Dictionary<int, BlockingQueue<KeyValuePair<byte[], int>>>(maximumConnections);
_receiveBufferQueue = new Dictionary<int, BlockingQueue<KeyValuePair<byte[], int>>>(10);

// Initialize the client multiplexer
_clientMultiplexer = new Dictionary<int, MultiplexerData>(maximumConnections);
_clientMultiplexer = new Dictionary<int, MultiplexerData>(10);

// Create the pools
_messageStatePool = new Pool<MessageState>(maximumConnections, () => new MessageState(), messageState =>
Expand All @@ -143,15 +143,15 @@ private SimplSocket(Func<Socket> socketFunc, EventHandler<SocketErrorArgs> error
messageState.TotalBytesToRead = -1;
});
_manualResetEventPool = new Pool<ManualResetEvent>(maximumConnections, () => new ManualResetEvent(false), manualResetEvent => manualResetEvent.Reset());
_bufferPool = new Pool<byte[]>(maximumConnections * 10, () => new byte[messageBufferSize], null);
_bufferPool = new Pool<byte[]>(maximumConnections, () => new byte[messageBufferSize], null);
_receiveMessagePool = new Pool<ReceivedMessage>(maximumConnections, () => new ReceivedMessage(), receivedMessage =>
{
receivedMessage.Message = null;
receivedMessage.Socket = null;
});

// Populate the pools
for (int i = 0; i < maximumConnections; i++)
// Populate the pools at 20%
for (int i = 0; i < maximumConnections / 5; i++)
{
_messageStatePool.Push(new MessageState());
_manualResetEventPool.Push(new ManualResetEvent(false));
Expand Down Expand Up @@ -207,7 +207,7 @@ public bool Connect(EndPoint endPoint)
{
_socket.Connect(endPoint);
}
catch (SocketException ex)
catch (SocketException)
{
_isDoingSomething = false;
return false;
Expand All @@ -217,20 +217,21 @@ public bool Connect(EndPoint endPoint)
var messageState = _messageStatePool.Pop();
messageState.Data = new MemoryStream();
messageState.Handler = _socket;
// Get a buffer from the buffer pool
var buffer = _bufferPool.Pop();

// Create receive queue for this client
_receiveBufferQueueLock.EnterWriteLock();
try
{
_receiveBufferQueue[messageState.Handler.GetHashCode()] = new BlockingQueue<KeyValuePair<byte[], int>>(_maximumConnections * 10);
_receiveBufferQueue[messageState.Handler.GetHashCode()] = new BlockingQueue<KeyValuePair<byte[], int>>(10);
}
finally
{
_receiveBufferQueueLock.ExitWriteLock();
}

// Get a buffer from the buffer pool
var buffer = _bufferPool.Pop();

// Post a receive to the socket as the client will be continuously receiving messages to be pushed to the queue
_socket.BeginReceive(buffer, 0, buffer.Length, 0, ReceiveCallback, new KeyValuePair<MessageState, byte[]>(messageState, buffer));

Expand Down Expand Up @@ -519,7 +520,7 @@ private void AcceptCallback(IAsyncResult asyncResult)
_receiveBufferQueueLock.EnterWriteLock();
try
{
_receiveBufferQueue[messageState.Handler.GetHashCode()] = new BlockingQueue<KeyValuePair<byte[], int>>(_maximumConnections * 10);
_receiveBufferQueue[messageState.Handler.GetHashCode()] = new BlockingQueue<KeyValuePair<byte[], int>>(10);
}
finally
{
Expand Down

0 comments on commit a9a8969

Please sign in to comment.