I have an API in which i do a lot of processing like sending a service bus queue message and receiving it, adding entries to table and then finally send an event to socket.io server. I want all this to be protected by concurrent executions. I am using Lock, but it doesnt seem to do the trick. Am i missing anything? below is my code
public class BroadcastController : ApiController
{
private readonly Object _Lock = new Object();
[HttpPost]
[ActionName("UploadRecording")]
public async Task<HttpResponseMessage> UploadRecording()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string path = Path.GetTempPath();
var provider = new MultipartFormDataStreamProvider(path);
// Read the form data and return an async task.
var response = await Request.Content.ReadAsMultipartAsync(provider);
// processing the mime content
lock (_Lock)
{
// sending and receiving service bus messages
// adding records to table
// sending an event to socket.io
return Request.CreateResponse(HttpStatusCode.OK, new ResponseMessage<PersistedAudioRecord> { SuccessCode = 1, Message = "Broadcast Uploaded", Data = updatedRecord });
} } }
Make the _Lock object static. Otherwise, you are using a different lock for each instance of the controller. Since the framework creates a new instance of the controller to process each request, each request is locking on a different _Lock object, thus providing no concurrency safety.
However, note that even a static lock object will only work if you have a single server. If you have multiple servers handling requests you'll need to manage concurrency by another means.
Related
I am using System.Net.Http.HttpClient to make postaysnc request. While request is in progress I unplug the network cable, receive HttpRequestException.
After some time plug the network cable again and make the postasync request, getting the HttpRequestException - sometimes i get the response server not available,sometimes timeout
Do i need to dispose the httpclient on exception and recreate when the request is made? How to make the query successful on network restore.
private async Task<string> GetServerResult()
{
try
{
var response = await myHttpClient.PostAsync("https://google.com", httpContent);
response.EnsureSuccessStatusCode();
}
catch (HttpRequestException ex)
{
throw new HttpRequestException(ex.Message, ex.InnerException);
}
}
As per your requirement, you have to change implement some sort of implementation in that case. My proposed solution is use to a caching mechanism at WCF Client and update it periodically.
The very simple implementation could be as: You have a very simple singleton class of and a periodic Timer fetches the data from your mentioned endpoint. It stores the last cached data so that you have a copy of the data and when the hits are failed you can configure a fallback mechanism for that. For instance you have an implementation like
//You single Cache class
public sealed class ClientCache
{
#region Singleton implementation
private static ClientCache _clientCache = new ClientCache();
private ClientCache()
{
}
public static ClientCache Instance => _clientCache;
#endregion
//Timer for syncing the data from Server
private Timer _timer;
//This data is the cached one
public string data = string.Empty;
internal void StartProcess()
{
//Initializing the timer
_timer = new Timer(TimeSpan.FromMinutes(1).TotalMilliseconds); //This timespan is configurable
//Assigning it an elapsed time event
_timer.Elapsed += async (e, args) => await SyncServerData(e, args);
//Starting the timer
_timer.Start();
}
//In this method you will request your server and fetch the latest copy of the data
//In case of failure you can maintain the history of the last disconnected server
private async Task ProcessingMethod(object sender, ElapsedEventArgs e)
{
//First we will stop the timer so that any other hit don't come in the mean while
timer.Stop();
//Call your api here
//Once the hit is completed or failed
//On Success you will be updating the Data object
//data = result from your api call
//Finally start the time again as
timer.Start();
}
}
Now coming to Step two where to initialize the ClientCache Class. The best options are to initialize it in Global.asax class
protected void Application_Start()
{
//As
ClientCache.Instance.StartProcess();
}
Now whenever your frontend calls the method you don't need to go back to the server. Just send back the result from your cache as:
private Task<string> GetServerResult()
{
return Task.FromResult(ClientCache.Instance.data);
}
I'm trying to maintain a list of WebSockets for a server which only needs to send messages to the client and not receive any replies. When the WebSocket is created initially all I want to do is just add the socket reference to a list for later use.
...
static Dictionary<int,WebSocket> wsDict = new Dictionary<int,WebSocket>();
...
private Task ProcessWS(AspNetWebSocketContext context)
{
wsDict[id] = (context.WebSocket);
...
}
(Finishes running the method and returns)
The issue I'm having is that I believe GC is disposing of the WebSocket, so when I try to use it at a later time I receive 'System.ObjectDisposedException'. Is there any way of permanently stopping GC from disposing of the socket?
Edit:
Sorry for not being clear originally, the whole class which inherits ApiController is (as the name suggests) is a control. A client initiates the WebSocket via a GET request and it calls the method above where it tries to store the socket into a dictionary (mapped to a int). The dictionary itself is Static.
It saves it into the Dict fine and in the debugger everything looks great. Its just literally disposing it after ProccessWS is complete and I can't seem to find a way to stop it. If I add a loop/sleep timer to the bottom of the ProcessWS it works fine - but thats not a viable solution.
The is a problem which originally I wasn't sure if it would be possible as each of the REST calls are stateless yet I need to maintain and overall list of all the connections which seems to contradict the original statement.
You have to await reads while the WS is still connected:
public class WSHandler : IHttpHandler
{
public bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(ProcessWS);
}
}
private async Task ProcessWS(AspNetWebSocketContext context)
{
WebSocket socket = context.WebSocket;
...
while (socket.State == WebSocketState.Open)
{
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None)
.ConfigureAwait(false);
...
}
}
}
I've got a multithreaded Windows service which is consuming messages off a Rabbit queue and sending emails based on the content of the messages.
When the rabbit client is initialized at startup, it limits the Threadpool threads with a Min and Max value.
For each message taken off the queue the service is sending an HTTP request to a web api service using HttpClient GetAsync method to retrieve email address.
The problem is that the request goes off to the data service, but the response never comes back. The windows service keeps consuming messages off the queue and hangs after a while (probably runs of of free threads) - it's waiting for any of the calls to web api to complete which they never do.
I was able to resolve the problem using a Semaphore class for the Rabbit loop rather than trying to limit the Threadpool directly, however, I'd like to know why the service got into this state in the first place. Is that to do with the GetAsync call? Is it perhaps freeing up the thread for the duration of the request, so that the main loop can steal it for a next request?
Any ideas?
The original loop:
while (!_stopped)
{
if (_paused) continue;
try
{
using (var messageBusReceiver = _rabbitQueueClient.ConfigureMessageBusReceiver())
{
using (_consumer = messageBusReceiver.Listen<PublishableItem>())
{
while (!_stopped)
{
if (_paused) continue;
_consumer.Consume(callback, consumeSynchronously: false);
_communicationErrorCount = 0;
}
}
}
}
The Consume method is eventually doing this:
_threadPoolProvider.QueueUserWorkItem(o =>
consumeMessage(callback, eventArgs, o), message);
The callback begins with the following lines - the null checking line is never reached:
var foo = _fooService.GetFoo(messageInfo.FooId);
if (foo == null)
{
throw new FooNotFoundException(
String.Format(CultureInfo.InvariantCulture, "Foo was not found for FooId of {0}", messageInfo.FooId));
}
The client method:
public Foo GetFoo(Guid id)
{
var path = getPathWithQueryStringAndDebug("getfoo", "id", id.ToString());
var response = _client.GetAsync(path).Result;
return processResponse<FooDto>(response);
}
I'm using asynchronous calls for communication to my server. I written some component to collect all unauthorized requests and to resend them after user logs in. I written some test to produce 10 threads that are sending some requests without first being authorized. Than I wait for 20 seconds and do authorization and after that I wait for request to successfully finish. But problem appeared at EndGetResponse method which I call in my callback method. I done that this way:
public void InternalCallback(IAsyncResult result)
{
try
{
RequestState state = (RequestState)result.AsyncState;
IHttpWebRequest request = state.Request;
using (IHttpWebResponse response = responseGetter.GetResponse(request, result))
{
// ...
}
}
// ...
}
So, I made some custom class RequestState which has some higher level callbacks I need and it has request which I'll use to call EndGetResponse method. But this way I got error:
IAsyncResult object was not returned from the corresponding asynchronous method.
I changed this so I now have Request field in my callback class which I set before calling BeginGetResponse and I use that Request field when calling EndGetResponse in my callback.
public void InternalCallback(IAsyncResult result)
{
try
{
using (IHttpWebResponse response = responseGetter.GetResponse(this.Request, result))
{
// ...
}
}
// ...
}
Is this new solution valid one? Can you suggest is this good way to do this or how should I do this?
I have a simple class that handles the connection being made between a client and server.
To let more than one user communicate with the server at one time each new Client connection is made on a separate thread.
In this class I create two streams that act as the inbound and outbound streams for the client. I create the fields first and then initialise the object in a separate method, simply because the object is used in several other places.
I've come to the point where I want to refactor the code to make it more robust, my first port of call was memory management. I've come to love the using() statement but noticed that I can't really see a way to do implement it due to the way the code is structured.
This means I have a fairly annoying method that is just used for closing the underlying connections and nothing more.
Furthermore, I came to implement exception handling and was curious whether the notion of wrapping the entire code in a method with a try{} statement and then having sequential catch() blocks with the applicable exception types was the best idea.
I hope I explained myself correctly, I'll post a snippet for you to look at.
Thanks!
//Fields
TcpClient tcpClient;
//The thread that will send information to the client
private Thread thrSender;
private StreamReader srReceiver;
private StreamWriter swSender;
private string currentUser;
private string strResponse;
//The constructor of the class takes in a TCP connection
public Connection(TcpClient tcpCon)
{
tcpClient = tcpCon;
//The thread that accepts the client and waits messages
thrSender = new Thread(AcceptClient);
//The thread calls the AcceptClient method
thrSender.Start();
}
private void CloseConnection()
{
//Close the currently open objects
tcpClient.Close();
srReceiver.Close();
swSender.Close();
}
//Occurs when a new client is accepted
private void AcceptClient()
{
srReceiver = new StreamReader(tcpClient.GetStream());
swSender = new StreamWriter(tcpClient.GetStream());
//Read account information from the client
currentUser = srReceiver.ReadLine();
//Examine response from client
if (currentUser != "")
{
//Store the user name in the hash table
if (ChatServer.htUsers.Contains(currentUser) == true)
{
//0 means not connected - Writes error to Client and Server log
swSender.WriteLine("0|This username already exists.");
swSender.Flush();
CloseConnection();
return;
}
//More if/else if/else statements
//...
}
}
You can dispose of the two streams fairly easily within the AcceptClient method by making them local variables since they aren't referenced elsewhere something like this:
private void AcceptClient()
{
using (StreamReader srReceiver = new StreamReader(tcpClient.GetStream()))
{
using (StreamWriter swSender = new StreamWriter(tcpClient.GetStream()))
{
// ...
}
}
}
The tcpClient is more tricky because it is being created on one thread and cleaned up on another. Unless you can change that then perhaps the best option is going to be to implement the cleanup within a try/finally.
private void AcceptClient()
{
try
{
using (StreamReader srReceiver = new StreamReader(tcpClient.GetStream()))
{
using (StreamWriter swSender = new StreamWriter(tcpClient.GetStream()))
{
// ...
}
}
}
finally
{
tcpClient.Dispose();
}
}
The finally clause will get called whether or not the try clause throws an exception.