Prerequisites
WindowsAzure.Storage V 9.3.3
Azure.Storage.Blobs V 12.6.0
Datadog APM monitoring
Context:
This is a known problem, that a blob client CreateIfNotExists(Async) returns 409 during execution, in case if a container already has been created before
Due to existed implementation, the CreateIfNotExists check is executing per a request, that mean a lot of times
As a result, there are a lot of 409 errors in a log & monitor systems
Also, it's kind of challenge to move logic to the app root, and, thus, to avoid per request CreateIfNotExists check
The possible fix, under consideration:
To mitigate the issue, I gonna to replace it with something like:
if (!await blobClient.ExistsAsync().ConfigureAwait(false))
{
await containerClient.CreateAsync().ConfigureAwait(false);
}
Question: And one moment that bothering me:
Could be such replacement become a concern within high concurrent workflow ?
P.s I've looked into CreateIfNotExistsAsync implementation at 'Azure.Storage.Blobs' nuget. From my point of view, nothing special about concurrency, but maybe I'm wrong. Pls. share you experience
Your code will have to handle this problem. Checking for existence won't help.
The problem is concurrency on the server side, not concurrency in the client. The source shows thatCretaeIfNotExists already handles the case of an existing container by simply ignoring the exception. One could ask why an exception is thrown instead of checking the status code, but the code doesn't throw a 409 if a container exists:
try
{
response = await CreateInternal(
publicAccessType,
metadata,
encryptionScopeOptions,
async,
cancellationToken,
operationName)
.ConfigureAwait(false);
}
catch (RequestFailedException storageRequestFailedException)
when (storageRequestFailedException.ErrorCode == BlobErrorCode.ContainerAlreadyExists)
{
response = default;
}
catch (Exception ex)
{
ClientConfiguration.Pipeline.LogException(ex);
scope.Failed(ex);
throw;
}
finally
{
ClientConfiguration.Pipeline.LogMethodExit(nameof(BlobContainerClient));
scope.Dispose();
}
return response;
For a conflict to occur, two CreateInternal calls would have to try to create the same non-existent container. That's why checking for existence won't help here. Even if an existence check was used, both clients would still try to execute Create at the same time and both would get a 409.
The application will have to handle this case. The best option would be reducing the chance of conflicts by not making this call on every request. This could be done by using eg a Lazy<> or asynchronous Lazy to make this call. Or using queued workers, reducing the number of calls that can happen at the same time.
The application would still have to handle the occasional 409. One way would be to simply retry CreateIfNotExists after a delay, until the call succeeds. That's better than calling Exists because the container's creation could fail.
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
if (!containerClient.Exists())
{
containerClient = await blobServiceClient.CreateBlobContainerAsync(containerName, PublicAccessType.BlobContainer);
}
Related
Right now, I'm not talking about ArgumentNullException or InvalidOperationException, but more or less only about HttpRequestException.
var responseAsync = httpClient.SendAsync(something);
try
{
var response = await responseAsync;
}
catch(Exception)
{
}
Will this code ever throw any exceptions, or can we safely assume that all the possible exceptions can only happen during the await?
"but more or less only about HttpRequestException"
MSDN:
The doco makes it quite clear:
HttpRequestException
The request failed due to an underlying issue such as network connectivity, DNS failure, server certificate validation or timeout.
So the answer would be "yes" if say your cat pulled out the network lead for example.
Will this code ever throw any exceptions,
Yes.
or can we safely assume that all the possible exceptions can only happen during the await?
It can occur on the following line too because by the time SendAsync returns (not to be confused with when the Task is complete), the Task has already been created and there is a tiny chance of it throwing before you get to the next line.
var responseAsync = httpClient.SendAsync(something);
EDIT: (from my comment below)
Also, for all we know, SendAsync might perform some "initial check" prior to the Task being created. In which case you'll need a try/catch on the above.
I have this code:
catch (Exception e)
{
try
{
transmitModel.AddAck(transmitBatchId,
"<error><message>" + e.Message + "</message><stack>" + e.StackTrace +
"</stack><Location>FromLisAtOMServer<Location>" +
"<TransmitBatchId>" + message.TransmitBatchId +
"</TransmitBatchId></error>", false, true);
}
// If we fail to log, we don't want that to bubble up...
// We want the real error to do that.
catch (Exception){}
// Re-throw the exception so that the service bus will
// move this off to the error queue.);
throw;
}
The AddAck method will save that string to the database (Using Entity Framework).
When I run this without the last statement throw, it saves my error message to database fine.
When I have the throw; in there, it says it saves but when I query the database it is not in there. I can even run a entity query via my data context right after saving (in the code) and it returns the value as if it is saved (though that may be using a cached version). But if I go and query afterwards the data is not there....
I have checked to be sure that no other logic is causing the value to be removed on an exception.
Any ideas what could be causing this?
OK, post as an answer here, it comes in my mind very easily as I used to met the same issue, and figured out it was just caused I didn't commit the DB transaction.
Thanks, :)
This call is as a result of an NServiceBus message.
I forgot that my NServiceBus stuff runs in a distributed transaction. So when I threw the exception it roll back all my pending changes.
I need to find out how to get this log file to post outside the transaction...
It is possible that NServiceBus provides hooks for this kind of thing.
Your problem is quite possibly what you have stated: the message handling has to happen in a transaction. You cannot commit that else you are also committing errors. So you definitely have to find out where you can hook into the post message handling exception processing.
With Shuttle ESB (http://shuttle.codeplex.com/) we use pipelines for handling different use cases and you can hook into the PipelineException event that is raised by the various pipelines. Shuttle has a the ability for developers to add modules that hook into the various events. There is already a SystemExceptionModule that does more-or-less what you want to do.
I'm developing a .Net Webform application, with heavy use of web services to communicate with an outside-server database.
So, I'm trying to find the best way to deal with disconnections and failures when calling a WS method.
For now, I've made a proxy function -kind of a layer- for every WS method I call, that repeats the specific WS call in a loop until it cames out successfully.
For Both Sync and Async calls, I've solved my problem, but I added an annoying extra layer to my WebService layer, with extra maintenance, and a lot of redundant code.
I refuse to believe there's not an existing solution for this standard situation, but can't find it anywhere.
Any Ideas?
Following, an example of my extra layer (Sync):
public static int WsMethod(string param1, int param2)
{
while(true)
{
try
{
return new Webpoint().WsMethod(param1, param2);
}
catch (Exception)
{
Thread.Sleep(new TimeSpan(0, 0, sleep_seconds));
}
}
}
And Async:
public static void WsMethodAsync(string param1, int param2, WsMethodCompletedEventHandler handler)
{
while (true)
{
try
{
var server = new Webpoint();
server.WsMethodAsyncCompleted += delegate(object sender, WsMethodAsyncCompletedEventArgs args)
{
if (args.Error != null)
{
Thread.Sleep(new TimeSpan(0, 0, sleep_seconds));
this.WsMethodAsync(param1, param2, handler);
}
else
{
handler(sender, args);
}
};
server.WsMethodAsyncAsync(param1, param2);
return;
}
catch (Exception)
{
Thread.Sleep(new TimeSpan(0, 0, sleep_seconds));
}
}
}
I would not recommend this pattern. If there is some problem with the parameters on your call this will run forever.
Normaly I would catch the few expected exceptions (CommunicationException, SocketException, whatever you need) and return some status-code for this (Ok, or NoNetwork, or whatever).
Or wrap up all expected exceptions into a MyCommunicationException and throw this (to hide implementation details from the caller and make exception-handling easier for it)
But give the control back to the caller and let the caller decide how to go on. Don't catch the other unexpected exceptions or rethrow them.
The caller can then decide to try time and again or 3-times or whatever.
If something were genuinely wrong with the service, or the connection thereto, or the request being made, then this would repeat indefinitely without ever telling you what's wrong.
What are the implications of the service call failing? How often does it really fail? And, most importantly, for what reason does it fail? If the reason is something that can be fixed, it should be fixed. Not worked around.
As a simple example, if this back-end service call is something initiated by a user of the website (say, they're trying to fetch some data to edit) then if the call fails you just present an error to the user. Something like:
"I'm sorry, but that data is not available at this time. The support team has been notified of this problem. Please try your request again. If the problem persists, contact the help desk at 800-555-1234."
Now, this shouldn't just be a single generic error to show the user no matter what happens. The code needs to be robust enough to discern one kind of error from another. If the service is unreachable, this error applies. If the service is saying that the request is invalid, then there's something wrong either with that the user is doing or what your code is doing, and that needs to be fixed. Etc.
How you deal with the errors and maintain a usable application is ultimately up to you and the business overall. But I honestly can't recommend the approach you outline on the question. That approach doesn't solve anything, it just ignores the problem until it gets worse. You need to determine the root cause of the errors and address that, not ignore them.
Also, any time an error is suppressed/ignored, a kitten dies.
I've taken the advice I've seen in other answered questions about when to throw exceptions but now my APIs have new noise. Instead of calling methods wrapped in try/catch blocks (vexing exceptions) I have out argument parameters with a collection of errors that may have occurred during processing. I understand why wrapping everything in a try/catch is a bad way to control the flow of an app but I rarely see code anywhere that reflects this idea.
That's why this whole thing seems so strange to me. It's a practice that is supposedly the right way to code but I don't see it anywhere. Added to that, I don't quite understand how to relate to client code when "bad" behavior has occured.
Here's a snippet of some code I'm hacking around with that deals with saving pictures that are uploaded by users of a web app. Don't sweat the details (it's ugly), just see the way I've added these output parameters to everything to get error messages.
public void Save(UserAccount account, UserSubmittedFile file, out IList<ErrorMessage> errors)
{
PictureData pictureData = _loader.GetPictureData(file, out errors);
if(errors.Any())
{
return;
}
pictureData.For(account);
_repo.Save(pictureData);
}
Is this the right idea? I can reasonably expect that a user submitted file is in some way invalid so I shouldn't throw an exception, however I'd like to know what was wrong with the file so I produce error messages. Likewise, any client that now consumes this save method will also want to find out what was wrong with the overall picture saving operation.
I had other ideas about returning some status object that contained a result and additional error messages but that feels weird. I know having out parameters everywhere is going to be hard to maintain/refactor/etc.
I would love some guidance on this!
EDIT: I think the user submitted files snippet may lead people to think of exceptions generated by loading invalid images and other "hard" errors. I think this code snippet is a better illustration of where I think the idea of throwing an exception is being discouraged.
With this I'm just saving a new user account. I do a state validation on the user account and then I hit the persistent store to find out if the username has been taken.
public UserAccount Create(UserAccount account, out IList<ErrorMessage> errors)
{
errors = _modelValidator.Validate(account);
if (errors.Any())
{
return null;
}
if (_userRepo.UsernameExists(account.Username))
{
errors.Add(new ErrorMessage("Username has already been registered."));
return null;
}
account = _userRepo.CreateUserAccount(account);
return account;
}
Should I throw some sort of validation exception? Or should I return error messages?
Despite the performance concerns, I think it's actually cleaner to allow Exceptions to be thrown out of a method. If there are any exceptions that can be handled within your method, you should handle them appropriately, but otherwise, let them bubble up.
Returning errors in out parameters, or returning status codes feels a bit clunky. Sometimes when faced with this situation, I try to imagine how the .NET framework would handle the errors. I don't believe there are many .NET framework methods that return errors in out parameters, or return status codes.
By definition, "exception" means an exceptional circumstance from which a routine cannot recover. In the example you provided, it looks like that means the image was invalid/corrupt/unreadable/etc. That should be thrown and bubbled up to the topmost layer, and there decide what to do with the exception. The exception itself contains the most complete information about what went wrong, which must be available at the upper levels.
When people say you should not use exceptions to control program flow, what they mean is: (for example) if a user tries to create an account but the account already exists, you should not throw an AccountExistsException and then catch it higher up in the application to be able to provide that feedback to the user, because the account already existing is not an exceptional case. You should expect that situation and handle it as part of your normal program flow. If you can't connect to the database, that is an exceptional case.
Part of the problem with your User Registration example is that you are trying to encapsulate too much into a single routine. If your method tries to do more than one thing, then you have to track the state of multiple things (hence things getting ugly, like lists of error messages). In this case, what you could do instead is:
UsernameStatus result = CheckUsernameStatus(username);
if(result == UsernameStatus.Available)
{
CreateUserAccount(username);
}
else
{
//update UI with appropriate message
}
enum UsernameStatus
{
Available=1,
Taken=2,
IllegalCharacters=3
}
Obviously this is a simplified example, but I hope the point is clear: your routines should only try to do one thing, and should have a limited/predictable scope of operation. That makes it easier to halt and redirect program flow to deal with various situations.
I think this is the wrong approach. Yes, it's very likely that you'll get occasional invalid images. But that's still the exceptional scenario. In my opinions, exceptions are the right choice here.
In situations like you have I usually throw a custom exception to the caller. I have a bit of a different view on exceptions maybe than others have: If the method couldn't do what it is intended to do (ie. What the method name says: Create a user account) then it should throw an exception - to me: not doing what you're supposed to do is exceptional.
For the example you posted, I'd have something like:
public UserAccount Create(UserAccount account)
{
if (_userRepo.UsernameExists(account.Username))
throw new UserNameAlreadyExistsException("username is already in use.");
else
return _userRepo.CreateUserAccount(account);
}
The benefit, for me at least, is that my UI is dumb. I just try/catch any function and messagebox the exception message like:
try
{
UserAccount newAccount = accountThingy.Create(account);
}
catch (UserNameAlreadyExistsException unaex)
{
MessageBox.Show(unaex.Message);
return; // or do whatever here to cancel proceeding
}
catch (SomeOtherCustomException socex)
{
MessageBox.Show(socex.Message);
return; // or do whatever here to cancel proceeding
}
// If this is as high up as an exception in the app should bubble up to,
// I'll catch Exception here too
This is similar in style to a lot of System.IO methods (http://msdn.microsoft.com/en-us/library/d62kzs03.aspx) for an example.
If it becomes a performance problem, then I'll refactor to something else later, but I've never needed to squeeze performance out of a business app because of exceptions.
I would allow for exceptions as well but based on your thread your looking for an alternative. Why not include a status or error information in your PictureData object. You can then just return the object with the errors in it and the other stuff left empty. Just a suggestion, but you are pretty much doing exactly what exceptions were made to solve :)
First off, exceptions should never be used as a control-flow mechanism. Exceptions are an error propagation and handling mechanism, but should never be used to control program flow. Control flow is the domain of conditional statements and loops. That is quite often a critical misconception that many programmers make, and is usually what leads to such nightmares when they try to deal with exceptions.
In a language like C# which offers structured exception handling, the idea is to allow 'exceptional' cases in your code to be identified, propagated, and eventually handled. Handling is generally left to the highest level of your application (i.e. a windows client with a UI and error dialogs, a web site with error pages, a logging facility in the message loop of a background service, etc.) Unlike Java, which uses checked exception handling, C# does not require you to specifically handle every single exception that may pass through your methods. On the contrary, trying to do so would undoubtedly lead to some severe performance bottlenecks, as catching, handling, and possibly re-throwing exceptions is costly business.
The general idea with exceptions in C# is that if they happen...and I stress if, because they are called exceptions due to the fact that during normal operation, you shouldn't be encountering any exceptional conditions, ...if they happen then you have the tools at your disposal to safely and cleanly recover and present the user (if there is one) with a notification of the applications failure and possible resolution options.
Most of the time, a well written C# application won't have that many try/catch blocks in core business logic, and will have a lot more try/finally, or better yet, using blocks. For most code, the concern in response to an exception is to recover nicely by releasing resources, locks, etc. and allowing the exception to continue on. In your higher level code, usually in the outer message processing loop of an application or in the standard event handler for systems like ASP.NET, you'll eventually perform your structured handling with a try/catch, possibly with multiple catch clauses to deal with specific errors that need unique handling.
If you are properly handling exceptions and building code that uses exceptions in an appropriate way, you shouldn't have to worry about lots of try/catch/finally blocks, return codes, or convoluted method signatures with lots of ref and out parameters. You should see code more like this:
public void ClientAppMessageLoop()
{
bool running = true;
while (running)
{
object inputData = GetInputFromUser();
try
{
ServiceLevelMethod(inputData);
}
catch (Exception ex)
{
// Error occurred, notify user and let them recover
}
}
}
// ...
public void ServiceLevelMethod(object someinput)
{
using (SomeComponentThatsDisposable blah = new SomeComponentThatsDisposable())
{
blah.PerformSomeActionThatMayFail(someinput);
} // Dispose() method on SomeComponentThatsDisposable is called here, critical resource freed regardless of exception
}
// ...
public class SomeComponentThatsDisposable: IDosposable
{
public void PErformSomeActionThatMayFail(object someinput)
{
// Get some critical resource here...
// OOPS: We forgot to check if someinput is null below, NullReferenceException!
int hash = someinput.GetHashCode();
Debug.WriteLine(hash);
}
public void Dispose()
{
GC.SuppressFinalize(this);
// Clean up critical resource if its not null here!
}
}
By following the above paradigm, you don't have a lot of messy try/catch code all over, but your still "protected" from exceptions that otherwise interrupt your normal program flow and bubble up to your higher-level exception handling code.
EDIT:
A good article that covers the intended use of exceptions, and why exceptions aren't checked in C#, is the following interview with Anders Heijlsberg, the chief architect of the C# language:
http://www.artima.com/intv/handcuffsP.html
EDIT 2:
To provide a better example that works with the code you posted, perhaps the following will be more useful. I'm guessing at some of the names, and doing things one of the ways I've encountered services implemented...so forgive any license I take:
public PictureDataService: IPictureDataService
{
public PictureDataService(RepositoryFactory repositoryFactory, LoaderFactory loaderFactory)
{
_repositoryFactory = repositoryFactory;
_loaderFactory = loaderFactory;
}
private readonly RepositoryFactory _repositoryFactory;
private readonly LoaderFactory _loaderFactory;
private PictureDataRepository _repo;
private PictureDataLoader _loader;
public void Save(UserAccount account, UserSubmittedFile file)
{
#region Validation
if (account == null) throw new ArgumentNullException("account");
if (file == null) throw new ArgumentNullException("file");
#endregion
using (PictureDataRepository repo = getRepository())
using (PictureDataLoader loader = getLoader())
{
PictureData pictureData = loader.GetPictureData(file);
pictureData.For(account);
repo.Save(pictureData);
} // Any exceptions cause repo and loader .Dispose() methods
// to be called, cleaning up their resources...the exception
// bubbles up to the client
}
private PictureDataRepository getRepository()
{
if (_repo == null)
{
_repo = _repositoryFactory.GetPictureDataRepository();
}
return _repo;
}
private PictureDataLoader getLoader()
{
if (_loader == null)
{
_loader = _loaderFactory.GetPictureDataLoader();
}
return _loader;
}
}
public class PictureDataRepository: IDisposable
{
public PictureDataRepository(ConnectionFactory connectionFactory)
{
}
private readonly ConnectionFactory _connectionFactory;
private Connection _connection;
// ... repository implementation ...
public void Dispose()
{
GC.SuppressFinalize(this);
_connection.Close();
_connection = null; // 'detatch' from this object so GC can clean it up faster
}
}
public class PictureDataLoader: IDisposable
{
// ... Similar implementation as PictureDataRepository ...
}
I have the following problem, basically i have a WCF service which operates fine in small tests. However when i attempt a batch/load test i get an InvalidOperationException with the message when the open() method is called on the proxy class:
"The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be modified while it is in the Opened state."
I have searched google, but cannot find anyone else really quoting this exception message.
I guess some further info on the service may be necessary for a diagnosis - when the service receives data through one of it's exposed methods, it basically performs some processing and routes the data to a service associated with the data (different data will result in different routing). To ensure that the service runs as quickly as possible, each cycle of receiving, processing and routing of the data is handled by a seperate thread in the threadpool. could this be a problem arising from one thread calling proxyClass.Open() whilst another is already using it? would a lock block eliminate this problem, if indeed this is the problem?
thanks guys, - ive been workikng on this project for too long, and finally want to see the back of it - but this appears to be the last stumbling block, so any help much appreciated :-)
=========================================================================
thanks for highlighting that i shouldn't be using the using construct for WCF proxy classes. However the MSDN article isn't the most clearly written piece of literature ever, so one quick question: should i be using a proxy as such:
try
{
client = new proxy.DataConnectorServiceClient();
client.Open();
//do work
client.Close();
}
.................. //catch more specific exceptions
catch(Exception e)
{
client.Abort();
}
How are you using proxy? Creating new proxy object for each call. Add some code regarding how you use proxy.
Desired way of using proxy is for each call you create new proxy and dispose it once completed. You are calling proxy.open() for opened proxy that is wrong. It should be just called once.
Try using something like below in finally, as wcf does not dispose failed proxy and it piles up. Not sure it would help but give it a shot.
if (proxy.State == CommunicationState.Faulted)
{
proxy.Abort();
}
else
{
try
{
proxy.Close();
}
catch
{
proxy.Abort();
}
}
Why to do this?
http://msdn.microsoft.com/en-us/library/aa355056.aspx
Code you posted above would work but you will alway be eating exception. So handle wcf related exception in seperate catch and your generic catch with Excelion would abort then throw exception.
try
{
...
client.Close();
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}
Also if you still want to use convenience of using statement then you can override dispose method in your proxy and dispose with abort method in case of wcf error.
And do not need to call .Open() as it will open when required with first call.
I'm assuming you're using .NET 3.5 or later. In .NET 3.5, the WCF ClientBase'1 class (base class for generated client proxies) was updated to use cached ChannelFactories/Channels. Consequently, unless you're using one of the Client use/creation strategies which disables caching (Client constructor that takes in a Binding object, or accessing one of a few certain properties before the backing channel is created), even though you're creating a new Client instance, it could very well still be using the same channel. In other words, before calling .Open(), always ensure you're checking the .Created status.
It definitely sounds like you've called Open() multiple times on the same object.
we hit the same roadblock as you sometime ago.
The issue with the using statement , is that if you get to a faulted state, it will still try to close at the end of the block. Another consideration, which was critical for us, is the cost of creating the proxy everytime.
We learned a lot from those blog posts:
http://blogs.msdn.com/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx
and
http://blogs.msdn.com/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx
Hopefuly it will help you as well.
Cheers, Wagner.