Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

abstract class BaseClientService supposed to be thread-safe, but is not #592

Closed
geroj opened this issue Sep 1, 2015 · 9 comments
Closed
Assignees
Labels
type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Milestone

Comments

@geroj
Copy link

geroj commented Sep 1, 2015

short description:

BaseClientService expose List Service.HttpClient.MessageHandler.ExceptionHandlers.Add(this);
This list can be accessed from several threads and cause application to crash.

long description:

I got several exceptions, when I used InsertMediaUpload request from namespace Google.Apis.Storage.v1 from multiple threads.

This class implements ResumableUpload, where entire upload is done.

Each exception was found in calling method UploadCoreAsync:

Object reference not set to an instance of an object.
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
   at Microsoft.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Google.Apis.Upload.ResumableUpload`1.<UploadCoreAsync>d__e.MoveNext() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\[Media]\Upload\ResumableUpload.cs:l
ine 459

or

Collection was modified; enumeration operation may not execute.
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
   at Microsoft.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Google.Apis.Upload.ResumableUpload`1.<UploadCoreAsync>d__e.MoveNext() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\[Media]\Upload\ResumableUpload.cs:line 459
Microsoft.Threading.Tasks

or

Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
   at System.Collections.Generic.List`1.RemoveAt(Int32 index)
   at System.Collections.Generic.List`1.Remove(T item)
   at Google.Apis.Upload.ResumableUpload`1.ServerErrorCallback.Dispose() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\[Media]\Upload\ResumableUpload.cs:line 273
   at Google.Apis.Upload.ResumableUpload`1.<UploadCoreAsync>d__e.MoveNext() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\[Media]\Upload\ResumableUpload.cs:line 463
mscorlib

Problem is in this part of code(method UploadCoreAsync) :
using (var callback = new ServerErrorCallback(this))
{
}

ServerErrorCallback is working with List ExceptionHandlers exposed by BaseClientService
Owner.Service.HttpClient.MessageHandler.UnsuccessfulResponseHandlers.Add(this);
Owner.Service.HttpClient.MessageHandler.ExceptionHandlers.Add(this);

Internal implementation (ConfigurableMessageHandler) is using List, so when I called code in UploadCoreAsync from several threads, it caused List to crash.

@LindaLawton LindaLawton added the type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. label Sep 2, 2015
@geroj
Copy link
Author

geroj commented Oct 19, 2015

Hi,

Is there any progress on this issue?

@peleyal
Copy link
Collaborator

peleyal commented Oct 20, 2015

Hi.. sorry for the huge delay...
So, this one is hard, since by solving this one we are going to break the current interface, but my suggestion will be as following (and it's true to UnsuccessfulResponseHandlers, ExceptionHandlers and ExecuteInterceptors lists)

  1. We need to find a PCL collection that is concurrent. I didn't find one yet, so the alternative will be when ever using one of those collection lock an object
  2. Expose AddUnsuccessfulResponseHandler and RemoveUnsuccessfulResponseHandlers (same for other collections)
  3. Remove the getters of those lists. No one outside should access them

It's a breaking change to the library. I'm a little bit concerned about it, but it will definitely fix the problem. We should solve it in the next weeks, if we break the API we will introduce it in 1.10.

I'll consider out options with jtattermusch@

Am I missing something? What are your thoughts about my suggestion geroj@?
Do you have a better proposal? I'll be happy to hear that...

Thanks!
Eyal

@peleyal peleyal added this to the 1.9.4 milestone Oct 20, 2015
peleyal added a commit to peleyal/google-api-dotnet-client that referenced this issue Oct 21, 2015
Solve googleapis#592. Change the API of ConfigurableMessageHandler to expose an
enumerable of handlers and interceptors and NOT a list.
@peleyal
Copy link
Collaborator

peleyal commented Oct 21, 2015

I created #617 in order to solve this issue. I'm still not 100% sure it's the right way, but I would like to get your opinions.
geroj@, Jan and Linda feel free to comment on #617.

Thanks!
Eyal

@peleyal peleyal modified the milestones: 1.10, 1.9.4 Oct 27, 2015
@peleyal
Copy link
Collaborator

peleyal commented Oct 27, 2015

I just committed #617. So I'm closing this one

@peleyal peleyal closed this as completed Oct 27, 2015
@peleyal
Copy link
Collaborator

peleyal commented Nov 12, 2015

Reopening this one, since we are still debating if we should break the existing API, with changing the return value of the list form IList to IEnumerable.

@peleyal peleyal reopened this Nov 12, 2015
peleyal added a commit to peleyal/google-api-dotnet-client that referenced this issue Nov 14, 2015
In googleapis#617, I presented a new breaking change to the library. With this
change we are going to avoid that, by adding back the list getter, which
is OBSOLETE now.
peleyal added a commit that referenced this issue Nov 17, 2015
Unbreaking change to ConfigurableMessageHandler (#592)
@peleyal
Copy link
Collaborator

peleyal commented Nov 17, 2015

I just submitted the change that isn't going to a introduce any breaking change in the coming release. We are safe to close this issue now.

@peleyal peleyal closed this as completed Nov 17, 2015
@geroj
Copy link
Author

geroj commented Dec 18, 2015

Thank you for this fix! When is it going to be released? I understand that this change will be in version 1.10

@peleyal
Copy link
Collaborator

peleyal commented Dec 18, 2015

It was just released earlier this week.
Enjoy!

@geroj
Copy link
Author

geroj commented Dec 18, 2015

Great, nice present for Christmas!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

No branches or pull requests

3 participants