Git Product home page Git Product logo

fusillade's Introduction

NuGet Stats Build Code Coverage


Fusillade: An opinionated HTTP library for Mobile Development

Fusillade helps you to write more efficient code in mobile and desktop applications written in C#. Its design goals and feature set are inspired by Volley as well as Picasso.

What even does this do for me?

Fusillade is a set of HttpMessageHandlers (i.e. "drivers" for HttpClient) that make your mobile applications more efficient and responsive:

  • Auto-deduplication of relevant requests - if every instance of your TweetView class requests the same avatar image, Fusillade will only do one request and give the result to every instance. All GET, HEAD, and OPTIONS requests are deduplicated.

  • Request Limiting - Requests are always dispatched 4 at a time (the Volley default) - issue lots of requests without overwhelming the network connection.

  • Request Prioritization - background requests should run at a lower priority than requests initiated by the user, but actually implementing this is quite difficult. With a few changes to your app, you can hint to Fusillade which requests should skip to the front of the queue.

  • Speculative requests - On page load, many apps will try to speculatively cache data (i.e. try to pre-download data that the user might click on). Marking requests as speculative will allow requests until a certain data limit is reached, then cancel future requests (i.e. "Keep downloading data in the background until we've got 5MB of cached data")

How do I use it?

The easiest way to interact with Fusillade is via a class called NetCache, which has a number of built-in scenarios:

public static class NetCache
{
    // Use to fetch data into a cache when a page loads. Expect that
    // these requests will only get so far then give up and start failing
    public static HttpMessageHandler Speculative { get; set; }

    // Use for network requests that are running in the background
    public static HttpMessageHandler Background { get; set; }

    // Use for network requests that are fetching data that the user is
    // waiting on *right now*
    public static HttpMessageHandler UserInitiated { get; set; }
}

To use them, just create an HttpClient with the given handler:

var client = new HttpClient(NetCache.UserInitiated);
var response = await client.GetAsync("http://httpbin.org/get");
var str = await response.Content.ReadAsStringAsync();

Console.WriteLine(str);

Where does it work?

Everywhere! Fusillade is a Portable Library, it works on:

  • Xamarin.Android
  • Xamarin.iOS
  • Xamarin.Mac
  • Windows Desktop apps
  • WinRT / Windows Phone 8.1 apps
  • Windows Phone 8

More on speculative requests

Generally, on a mobile app, you'll want to reset the Speculative limit every time the app resumes from standby. How you do this depends on the platform, but in that callback, you need to call:

NetCache.Speculative.ResetLimit(1048576 * 5/*MB*/);

Offline Support

Fusillade can optionally cache responses that it sees, then play them back to you when your app is offline (or you just want to speed up your app by fetching cached data). Here's how to set it up:

  • Implement the IRequestCache interface:
public interface IRequestCache
{
    /// <summary>
    /// Implement this method by saving the Body of the response. The
    /// response is already downloaded as a ByteArrayContent so you don't
    /// have to worry about consuming the stream.
    /// <param name="request">The originating request.</param>
    /// <param name="response">The response whose body you should save.</param>
    /// <param name="key">A unique key used to identify the request details.</param>
    /// <param name="ct">Cancellation token.</param>
    /// <returns>Completion.</returns>
    Task Save(HttpRequestMessage request, HttpResponseMessage response, string key, CancellationToken ct);

    /// <summary>
    /// Implement this by loading the Body of the given request / key.
    /// </summary>
    /// <param name="request">The originating request.</param>
    /// <param name="key">A unique key used to identify the request details,
    /// that was given in Save().</param>
    /// <param name="ct">Cancellation token.</param>
    /// <returns>The Body of the given request, or null if the search
    /// completed successfully but the response was not found.</returns>
    Task<byte[]> Fetch(HttpRequestMessage request, string key, CancellationToken ct);
}
  • Set an instance to NetCache.RequestCache, and make some requests:
NetCache.RequestCache = new MyCoolCache();

var client = new HttpClient(NetCache.UserInitiated);
await client.GetStringAsync("https://httpbin.org/get");
  • Now you can use NetCache.Offline to get data even when the Internet is disconnected:
// This will never actually make an HTTP request, it will either succeed via
// reading from MyCoolCache, or return an HttpResponseMessage with a 503 Status code.
var client = new HttpClient(NetCache.Offline);
await client.GetStringAsync("https://httpbin.org/get");

How do I use this with ModernHttpClient?

Add this line to a static constructor of your app's startup class:

using Splat;

Locator.CurrentMutable.RegisterConstant(new NativeMessageHandler(), typeof(HttpMessageHandler));

What do the priorities mean?

The precedence is UserInitiated > Background > Speculative Which means that anything set as UserInitiate has a higher priority than Background or Speculative.

Explicit is a special that allows to set an explicit value that can be higher, lower or in between any of the predefined cases.

var lowerThanSpeculative = new RateLimitedHttpMessageHandler(
                new HttpClientHandler(), 
                Priority.Explicit, 
                9);

var moreThanSpeculativeButLessThanBAckground = new RateLimitedHttpMessageHandler(
                new HttpClientHandler(), 
                Priority.Explicit, 
                15);

var doItBeforeEverythingElse = new RateLimitedHttpMessageHandler(
                new HttpClientHandler(), 
                Priority.Explicit, 
                1000);

Statics? That sucks! I like $OTHER_THING! Your priorities suck, I want to come up with my own scheme!

NetCache is just a nice pre-canned default, the interesting code is in a class called RateLimitedHttpMessageHandler. You can create it explicitly and configure it as-needed.

What's with the name?

The word 'Fusillade' is a synonym for Volley :)

Contribute

Fusillade is developed under an OSI-approved open source license, making it freely usable and distributable, even for commercial use. Because of our Open Collective model for funding and transparency, we are able to funnel support and funds through to our contributors and community. We ❤ the people who are involved in this project, and we’d love to have you on board, especially if you are just getting started or have never contributed to open-source before.

So here's to you, lovely person who wants to join us — this is how you can support us:

fusillade's People

Contributors

aigiol avatar albilaga avatar anaisbetts avatar chrispulman avatar dependabot-preview[bot] avatar dependabot[bot] avatar edhubbell avatar elipriaulx avatar ghuntley avatar giusepe avatar glennawatson avatar jgfaulk avatar kentcb avatar martijn00 avatar renovate[bot] avatar rlittlesii avatar worldbeater avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fusillade's Issues

How to use Fusillade without ModernHttpClient in Xamarin Forms?

Hi!
Considering that Stackoverflow does not have a tag for Fusillade, I'm not sure if I would get an answer there. I hope this is the right forum for this question, if not please excuse.

As per this article, I would deduce that the use of ModernHttpClient within a XF project would be redundant. Would you be able to guide me on how I could use Fusillade (with Refit) without ModernHttpClient?

Thanks in advance.

[BUG] Refit + Fusillade fails with System.ObjectDisposedException

Describe the bug
Actually the same as #34 witch is closed but not fixed.
Using Refit with Fusillade fails with System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net.Http.HttpConnectionResponseContent'.
The exception is thrown at Refit.RequestBuilderImplementation.d__15`1.MoveNext() in /_/Refit/RequestBuilderImplementation.cs:line 324
It seems that when Fusillade deduplicates requests returning val.Response.ToTask(cancellationToken), Refit fails deserializing HttpContent because it's disposed.

As @clairernovotny on the Refit side with issue #1048 think it looks like a Fusillade bug, I opened the same issue on the Fusillade side.
I don't know if the bug comes from Refit or Fusillade, but I know it throws when using one with each other.

Steps To Reproduce
Create a Refit RestService with any Fusillade's NetCache HttpMessageHandler into the HttpClient, and send the same request at least twice at the same time.
Something dummy like:

try
{
	var reqResService = RestService.For<IReqResService>(new HttpClient(NetCache.UserInitiated)
	{
		BaseAddress = new Uri("https://reqres.in/api")
	});

	var task1 = reqResService.GetUsersAsync();
	var task2 = reqResService.GetUsersAsync();

	var result = await Task.WhenAll(task1, task2);
	var userList = result.FirstOrDefault();
}
catch (Exception e)
{
	throw;
}

with IReqResService:

public interface IReqResService
{
	[Get("/users")]
	Task<UserList> GetUsersAsync();
}

and Models:

public class UserList
{
	[JsonProperty("page")]
	public int Page { get; set; }

	[JsonProperty("per_page")]
	public int PerPage { get; set; }

	[JsonProperty("total")]
	public int Total { get; set; }

	[JsonProperty("total_pages")]
	public int TotalPages { get; set; }

	[JsonProperty("data")]
	public List<User> Data { get; set; }
}

public class User
{
	[JsonProperty("id")]
	public int Id { get; set; }

	[JsonProperty("first_name")]
	public string FirstName { get; set; }

	[JsonProperty("last_name")]
	public string LastName { get; set; }

	[JsonProperty("avatar")]
	public string Avatar { get; set; }

	[JsonProperty("email")]
	public string Email { get; set; }
}

Well interface and models are not the point, it's just to illustrate the bug.
Note that everything succeed when using Fusillade without Refit, I mean using HttpClient directly like:

try
{
	var client = new HttpClient(NetCache.UserInitiated)
	{
		BaseAddress = new Uri("https://reqres.in/api/users")
	};

	var task1 = client.GetAsync("");
	var task2 = client.GetAsync("");

	var responses = await Task.WhenAll(task1, task2);
	var jsonString = await responses.First().Content.ReadAsStringAsync().ConfigureAwait(false);
	var userList = JsonConvert.DeserializeObject<UserList>(jsonString);
}
catch (Exception e)
{
	throw;
}

Note that everything succeed to, when using Refit without Fusillade like:

try
{
	var reqResService = RestService.For<IReqResService>("https://reqres.in/api");

	var task1 = reqResService.GetUsersAsync();
	var task2 = reqResService.GetUsersAsync();

	var result = await Task.WhenAll(task1, task2);
	var userList = result.FirstOrDefault();
}
catch (Exception e)
{
	throw;
}

So it's only when using both of it.

Expected behavior
Should return result

Environment

  • OS: All
  • Device: All
  • Version: All

Differing requests can be returned the same deduplicated response

It's possible that some differing requests receive the same response.

For example, making requests to the same endpoint, but with a different If-Modified-Since header, can result in the second request receiving the response from the first. These requests are perhaps being deduplicated when they should not be.

Our application makes use of the If-Modified-Since and If-None-Match headers. Looking at the UniqueKeyForRequest method, it appears that these headers are not taken into consideration. It also appears that non-idempotent requests such as POSTs may also be deduplicated, when a client may expect all of these requests to be send and responded to individually as state changes on the server.

Does this assessment seem on the right track, and would you accept a PR for these changes? Thanks!

ReactiveUI > 8.3.1 Incompatibility

Hello,

Love the project, but currently unusable with ReactiveUI 8.4.1 and greater.

Version conflict detected for System.Reactive. Reference the package directly from the project to resolve this issue.

Rfs.TracsMobile.Xamarin.Forms -> ReactiveUI.Events.XamForms 8.7.2 -> System.Reactive (>= 4.0.0)
Rfs.TracsMobile.Xamarin.Forms -> Rfs.TracsMobile.Xamarin.Core -> fusillade 1.0.0 -> System.Reactive (>= 3.1.1 && < 4.0.0).

Any suggestions or workarounds?

Thanks,

Chet

Refit + Fusillade fails with System.ObjectDisposedException: Cannot access a disposed objec

I have a xamarin forms project. I hoped to use both Refit and Fusillade for it.
When i use either of them everything works fine but when i start to use them together then requests fails.

Fusillade 1.0.0
Xamarin.Forms 3.0.0.296286
Refit 4.3.0

**Single ** request works fine. Fails only when Fusillade deduplicates queries.

The code is simple. I got an empty ContentPage with button and label.
The button click handler contains code:

var api = RestService.For<IScheduleApi>(
	new HttpClient( NetCache.UserInitiated )
	{
		BaseAddress = new Uri( Config.ApiUrl )
	} );
			
var result = await api.GetText();
this.TextLabel.Text = result;

IScheduleApi is the following:

[Headers("Accept: application/json")]
    public interface IScheduleApi
	{
		[Get("/schedule")]
		Task<string> GetText();
	}

The web service just sleeps and returns text:

Thread.Sleep(4000);
return "Text";

When i click on button and wait then i get the response and everything is fine.
When i click next time and again wait - everything works.
But if i do more that one click then i get the exeption. Though i am not sure which one of the libraries causes it

04-03 19:18:50.144 I/MonoDroid(10742): UNHANDLED EXCEPTION:
04-03 19:18:50.174 I/MonoDroid(10742): System.ObjectDisposedException: Cannot access a disposed object.
04-03 19:18:50.174 I/MonoDroid(10742): Object name: 'System.Net.Http.StreamContent'.
04-03 19:18:50.174 I/MonoDroid(10742): at System.Net.Http.HttpContent+d__18.MoveNext () [0x00027] in :0
04-03 19:18:50.174 I/MonoDroid(10742): --- End of stack trace from previous location where exception was thrown ---
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <fcbf47a04b2e4d90beafbae627e1fca4>:0 04-03 19:18:50.174 I/MonoDroid(10742): at Refit.RequestBuilderImplementation+<>c__DisplayClass11_01+<b__0>d[T].MoveNext () [0x003d2] in :0
04-03 19:18:50.174 I/MonoDroid(10742): --- End of stack trace from previous location where exception was thrown ---
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at TempStaff.SchedulePage+d__3.MoveNext () [0x00051] in D:\Code\Avilum\tempstaff\TempStaff\TempStaff\SchedulePage.xaml.cs:69
04-03 19:18:50.174 I/MonoDroid(10742): --- End of stack trace from previous location where exception was thrown ---
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__6_0 (System.Object state) [0x00000] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at Android.App.SyncContext+<>c__DisplayClass2_0.b__0 () [0x00000] in <551e90b840814b76a3d15b7bbaa8a77c>:0
04-03 19:18:50.174 I/MonoDroid(10742): at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <551e90b840814b76a3d15b7bbaa8a77c>:0
04-03 19:18:50.174 I/MonoDroid(10742): at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <551e90b840814b76a3d15b7bbaa8a77c>:0
04-03 19:18:50.174 I/MonoDroid(10742): at (wrapper dynamic-method) System.Object.aa6e990f-8152-4823-ae62-44e7a273b201(intptr,intptr)

Xamarin.iOS Warning MT3005 - System.Threading.Tasks dependency was not found

After the Xamarin.iOS updates this week, I am receiving this compiler warning. It also manifests in weird run time crashes when the linker runs.

Full error text is below:

Warning MT3005: The dependency 'System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of the assembly 'Fusillade, Version=0.6.0.0, Culture=neutral, PublicKeyToken=null' was not found. Please review the project's references. (MT3005)

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/ci-build.yml
.github/workflows/lock.yml
  • dessant/lock-threads v5
.github/workflows/release.yml
nuget
src/Directory.build.props
  • Roslynator.Analyzers 4.12.0
  • stylecop.analyzers 1.2.0-beta.556
  • Nerdbank.GitVersioning 3.6.133
  • coverlet.msbuild 6.0.2
  • PublicApiGenerator 11.1.0
  • FluentAssertions 6.12.0
  • Verify.Xunit 22.11.5
  • Xunit.StaFact 1.1.11
  • xunit.runner.visualstudio 2.5.7
  • xunit.runner.console 2.7.0
  • xunit 2.7.0
  • Microsoft.NET.Test.Sdk 17.9.0
  • Microsoft.SourceLink.GitHub 8.0.0
src/Fusillade.Tests/Fusillade.Tests.csproj
src/Fusillade/Fusillade.csproj
  • System.Reactive 6.0.0
  • System.Net.Http 4.3.4
src/global.json
  • dotnet-sdk 8.0.101
  • MSBuild.Sdk.Extras 3.0.44

  • Check this box to trigger a request for Renovate to run again on this repository

ModernHttpClient + PortableRest

Hi,

I noticed that Fusillade version 0.6 doesn't work with ModernHttpClient + PortableRest (Xamarin.Forms project), but adding the reference directly to Fusillade code works. Could you generate a new version for Fusillade since the latest one is from 2014?

Thanks,

Image request in Fusillade

I am trying to the "Auto-deduplication of requests" feature on Fusillade. I try to fetch a same image 10 times. And it is sending 10 requests to the server. The url is same for all requests. Am I doing something wrong?

Here is the sample test code:

 Uri u =  new Uri("http://www.brandeis.edu/about/images/newformat/map2.jpg");
 for (int i = 0; i < 10; i++)
  {
                HttpClient hc = new HttpClient(NetCache.UserInitiated);
                var s = await hc.GetAsync(u);

                var st = await s.Content.ReadAsStreamAsync();
}

Method 'Fusillade.RateLimitedHttpMessageHandler..ctor' not found.

Note: for support questions, please ask on StackOverflow: https://stackoverflow.com/questions/tagged/Fusillade . This repository's issues are reserved for feature requests and bug reports.

Do you want to request a feature or report a bug?

bug

What is the current behavior?

I upgraded our nuget package and I am getting this error. Any ideas?

private T Background
{
get
{
return new Lazy(() => createClient(
new RateLimitedHttpMessageHandler(new NativeMessageHandler(), Priority.Background))).Value;
}
}

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem

What is the expected behavior?

What is the motivation / use case for changing the behavior?

Which versions of Fusillade, and which platform / OS are affected by this issue? Did this work in previous versions of ReativeUI? Please also test with the latest stable and snapshot (https://www.myget.org/feed/Fusillade/package/nuget/Fusillade) versions.

Other information (e.g. stacktraces, related issues, suggestions how to fix)

An exception was thrown by the type initializer for Fusillade.NetCache

So I migrated to the Xamarin.iOS unified-API, and all works fine on an iOS simulator, when I try to run on my iPhone 5S, it crashes on startup with no exceptions thrown.

All I get is a message in the application output window "An exception was thrown by the type initializer for Fusillade.NetCache".

POST requests are being de-duplicated

Spurious POST requests are being de-duplicated. For me, this meant that only some data was being submitted to the server, and the rest was being silently dropped :(

I worked around this by sticking this at the start of RateLimitedHttpMessageHandler.SendAsync:

            if (request.Method == HttpMethod.Post)
            {
                return base.SendAsync(request, cancellationToken);
            }

I believe other methods should also be excluded from de-duplicating, such as PUT. If we can agree here on what methods should be excluded, and whether the above approach is fine, I'm happy to submit a PR.

Project still active?

Hey yall, first off thanks (Paul/Geoff/Martijn) for everything you guys do in the Xamarin space. Being new to Xamarin, I've heavily relied on both your online content as well as code to spin up and be productive.

I caught an older talk by Paul that mentioned this project, and being familiar w/ Volley on the Android side I figured it was worth a look. I notice that things haven't been updated in a while now so I was just wondering if you consider the project active or not. No worries if not, you don't owe me anything, I just didn't necessarily want to integrate it into my project if not : )

Thanks again!

Fusillade install failed due to Rx-Interfaces

Hi,

I have tried to install Fusillade on a PCL (.NetPortable4.5), but it fails when installing dependency Rx-Interfaces 2.2.4.

Tried multiple profiles: 7, 11, 259

Failure report:
Error Could not install package 'Rx-Interfaces 2.2.4'. You are trying to install this package into a project that targets '.NETPortable,Version=v4.5,Profile=Profile259', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author. 0

[BUG] Crashing on iOS when aeroplane mode enabled.

Describe the bug

When using Fusilade as a httpmessagehandler in an iOS app via

var httpHandler = new Fusillade.RateLimitedHttpMessageHandler(
                            new NSUrlSessionHandler(),
                            Fusillade.Priority.Background);
                        var httpClient = new System.Net.Http.HttpClient(httpHandler)
                        {
                            BaseAddress = uri
                        };

the app will crash when wifi and cellular is disabled(no data).

Steps To Reproduce

Expected behavior

App should work without crashing even if it does not have internet access.

Screenshots

Environment

  • OS: iOS 12.4.8
  • Device: iPhone 6
  • Version: 2.2.9
  • Working Version: None that I know of?

Additional context

Crash stack trace:

error	15:07:29.424320+1000	Life	Task <B0D7871B-099F-4E4E-A62C-57BB7A36EC01>.<1> finished with error [-1009] Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={_kCFStreamErrorCodeKey=50, NSUnderlyingError=0x2837c0030 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 UserInfo={_kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=<private>, _NSURLErrorRelatedURLSessionTaskErrorKey=<private>, NSLocalizedDescription=The Internet connection appears to be offline., NSErrorFailingURLStringKey=<private>, NSErrorFailingURLKey=<private>, _kCFStreamErrorDomainKey=1}
default	15:07:29.428785+1000	Life	Execution aborted in method: <<SendAsync>b__2>d::MoveNext
default	15:07:29.428833+1000	Life	Line=6471 IP=0x6623a21, Aborted execution
default	15:07:29.428864+1000	Life	0x6623a21 26f
default	15:07:29.428900+1000	Life	error: * Assertion: should not be reached at /Users/builder/jenkins/workspace/archive-mono/2020-02/ios/release/mono/mini/interp/interp.c:508

Requests that fail cannot be retried

While testing my mobile app under bad network conditions, I noticed that if I make a request when a network connection is not available, an exception is thrown stating there is no internet connection as expected. However, if the network connection becomes available and I make the same request again the same exception is thrown no matter how many times I retry.

I think this is because the operation that gets enqueued on lines 99 - 124 in RateLimitedHttpMessageHandler.cs does not handle network exceptions that may be thrown as a result of the call on line 99. Any exceptions thrown in this operation would cause line 123 to never run and therefore the in-flight response to never be removed. When the request is retried the same unique key is generated and the previously failed response gets returned.

[Bug]: Azure Blob image URL will throw an exception when there are invalid values

Describe the bug 🐞

A bug happened!

Azure Blob image URL will throw an exception when there are invalid values

https://github.com/reactiveui/Fusillade/blob/2.4.67/src/Fusillade/RateLimitedHttpMessageHandler.cs#L176-L180

Changing here should fix this issue
Use HttpHeaders.TryAddWithoutValidation Method

e6644dad5a1d1c15191594e408c59b2b

https://blob.steampp.net:443/jpeg/deb006f3186f2bf5c905f8e55f3d35e7bf24319a2f2143ab4cafffc5fcc00f817e30bd6d2c3a580d4423755f4f8f08f2.jpg

fe9be287cdb946f48556bbe2bfacefd8

Step to reproduce

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Reproduction repository

https://github.com/reactiveui/ReactiveUI

Expected behavior

This should happen...

Screenshots 🖼️

No response

IDE

No response

Operating system

No response

Version

No response

Device

No response

ReactiveUI Version

No response

Additional information ℹ️

No response

Add package issues with Rx-Main

Hi,

I would like to use Fusillade into a PCL Xamarin Forms project, but I failed to add the package. It seems there's an issue with RX-Main dependency. Here is what the message I get into the console :

Could not install package 'Rx-Interfaces 2.2.4'. You are trying to install this package into a project that targets '.NETPortable,Version=v4.5,Profile=Profile259'

OK, so I guess it's just that Rx-Main (and its dependencies) doesn't support PCL Profile259 at all (which is weird because when I open the package, there's the right folder in the lib directory).

When I get that kind of error, I always search the package page on Nuget to look at the supported platforms, which I did. But this time, it looks like Rx-Main is not on Nuget anymore and has been unpublished by MS :

https://www.nuget.org/packages/rx-main

It says :

"The owner has unlisted this package. This could mean that the package is deprecated or shouldn't be used anymore."

Could you please update Rx-Main dependency with their new library for Reactive ?
https://www.nuget.org/packages/System.Reactive/

It supports net-standard 1.0 and should be usable once I migrate my PCL project to .Net Standard.

Many Thanks !

UniqueKeyForRequest and POST body content

RateLimitedHttpMessageHandler:UniqueKeyForRequest doesn't take into account the content of the HttpRequestMessage when it is a POST request. POST requests which are similar and just have a different content, are considered the same request and only the first one is executed when multiple of those similar POST requests are outstanding. All calls receive the same response while they should actually receive different responses.

Update NuGet Package

The NuGet available on nuget.org does not include the critical #15 fix. Can someone update it? @paulcbetts? Thanks.

What do the priorities mean?

I see the following priorities defined in the library but not all of them are spelled out in the read me. Could someone please shed some light on what each means and when to use them? Explicit is never mentioned at all.

public enum Priority
  {
    Explicit = 0,
    Speculative = 10,
    Background = 20,
    UserInitiated = 100,
  }

Using Fusillade with async / await with PCL Profile7 for Xamarin.IOS host crashes app

First of all thanks for such a nice package!

I'm experiencing some weird behavior using Fusillade with async / await with PCL Profile7 for Xamarin.IOS host crashes the app, here is the callstack:
screen shot 2016-02-07 at 6 20 28 pm

I tried with many other PCL profiles - same result. I tried avoid async / await - and it was successfully working using just httpClient.PostAsync.Result - but I want to avoid it in our solution.
I tried to avoid using PCL library by using just Xamarin.IOS without PCL shared project - and it was working successfully, though in some logs from our beta we received async / await app crashes - but I cannot tell if Fusillade was the cause.

Tried to use HttpClient without Fusillade with all mentioned-above cases - working like charm.
I know it could be some weird PCL mambo-jambo - but still I think it is helpful to letting you know.

Looking forward for a fix
Thanks!

NuGet Package - Warning on every build

The DLL provided by the NuGet package generates the following warnings on every build in Xamarin Studio. I've switched over to a compiled version of the sources and no such build warning occurs.

MTOUCH:  warning MT3005: The dependency 'System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of the assembly 'Fusillade, Version=0.6.0.0, Culture=neutral, PublicKeyToken=null' was not found. Please review the project's references.
MTOUCH:  warning MT3006: Could not compute a complete dependency map for the project. This will result in slower build times because Xamarin.iOS can't properly detect what needs to be rebuilt (and what does not need to be rebuilt). Please review previous warnings for more details.
MTOUCH:  warning MT3005: The dependency 'System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of the assembly 'Fusillade, Version=0.6.0.0, Culture=neutral, PublicKeyToken=null' was not found. Please review the project's references.
MTOUCH:  warning MT3006: Could not compute a complete dependency map for the project. This will result in slower build times because Xamarin.iOS can't properly detect what needs to be rebuilt (and what does not need to be rebuilt). Please review previous warnings for more details.

Circular dependency detected

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

Try to install the Fusillade NuGet package into my Xamarin.Android project. Get the error: Circular dependency detected 'fusillade 1.0.0 => System.Reactive 3.1.1 => System.Reactive.PlatformServices 4.0.0 => System.Reactive 3.1.1'.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem

  • Create a new Xamarin.Android project.
  • Install the Fusillade package from NuGet.

What is the expected behavior?

The Package installs

What is the motivation / use case for changing the behavior?

Which versions of Fusillade, and which platform / OS are affected by this issue? Did this work in previous versions of ReativeUI? Please also test with the latest stable and snapshot (https://www.myget.org/feed/Fusillade/package/nuget/Fusillade) versions.

Fusillade: 1.0.0
VS4Mac: 7.5.3

Other information (e.g. stacktraces, related issues, suggestions how to fix)

Possibly updating the packages may fix the issue.

A message handler for authentication

Hi Paul!

I'm currently working on a project where I authenticate every api call using OAuth2/OpenId. To use this within the Fusillade stack, I've created a message handler which will do the api request, and if the request fails because the token has expired (unauthorized response), I'll post a new request to refresh the token, and re-post the original api request.

Now I would like optimize it. Currently, some of my views are making calls to my api in a concurrent way, all with a different priority. From what I see, there are at least 3 concurrent api requests at one time. Now when the token has expired, each of those concurrent api request will fail and all of them will refresh the token. I'd like only one request to refresh the token and pass its result to the other two. After the token has been refreshed, all concurrent requests should execute again.

How would you implement such a message handler?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.