OnMessageAsync() not always triggering - message-queue

Below is the exact code for my Azure Service Fabric Service Bus queue listener.
The problem I am having is that the _client.OnMessageAsync "takes a rest" when not used for a few minutes. It eventually wakes up and processes the queued messages, maybe within 5 minutes. messages are never dropped or deadletter'd, but this is unacceptable behavior. I tried tweaking message options, but nada..
Any ideas?
internal sealed class Core : StatelessService
{
readonly QueueClient _client;
readonly OnMessageOptions _msgOptions;
public Core(StatelessServiceContext context)
: base(context)
{
var connectionString = CloudConfigurationManager.GetSetting(Resources.ServiceBusConnectionString);
var inQueue = CloudConfigurationManager.GetSetting(Resources.InQueue);
var factory = MessagingFactory.CreateFromConnectionString(connectionString);
_client = factory.CreateQueueClient(inQueue, ReceiveMode.PeekLock);
_msgOptions = new OnMessageOptions
{
AutoComplete = false,
MaxConcurrentCalls = 5
};
}
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[0];
}
protected override async Task RunAsync(CancellationToken cancellationToken)
{
await Task.Run(() =>
_client.OnMessageAsync(
async message =>
{
OnReceived(message);
await message.CompleteAsync();
}, _msgOptions),
cancellationToken);
}
private void OnReceived(BrokeredMessage brokeredMessage)
{
var message = brokeredMessage.GetBody<Message>();
ServiceEventSource.Current.ServiceMessage(Context, "Working-{0}", message.Transaction.Id);
var preocessor = new Processor();
preocessor.Process(message);
}
}

Related

StateHasChanged not updating on Blazor server app

I am working on a Blazor Server app over a SignalR connection with an ASP.NET Core API, this code works fine in WebAssembly but for some reason it doesn't works in Blazor Server app.
I suspect the problem is that StateHasChanged() isn't making effect, since Console.WriteLine($"Company Name: {item.CompanyName}, Volumn: {item.Volume}"); is printing in console but MarketData isn't updating UI at StateHasChanged().
For more context; full code is explained here:
https://www.webnethelper.com/2022/01/aspnet-core-6-signalr-creating-real.html
But I guess it's just a common fix; but I can't find the solution.
I've also tried with InvokeAsync(() => StateHasChanged()); as mentioned here in stackoverflow but It didnt work. Can anyone help me fix this issue?
private HubConnection? hubConn;
private string? ConnectionStatusMessage;
public List<Market> MarketData = new List<Market>();
public List<Market> MarketReceivedData = new List<Market>();
private List<string> xSource;
private List<int> ySource;
private List<object> source;
protected override async Task OnInitializedAsync()
{
xSource = new List<string>();
ySource = new List<int>();
source = new List<object>();
await service.GetMarketEndpoint();
await Start();
}
private async Task Start()
{
hubConn = new HubConnectionBuilder().WithUrl("https://localhost:7193/marketdata").Build();
await hubConn.StartAsync();
if(hubConn.State == HubConnectionState.Connected )
ConnectionStatusMessage = "Connection is established Successfully...";
else
ConnectionStatusMessage = "Connection is not established...";
}
private void MarketDataListener(string chartType)
{
hubConn.On<List<Market>>("SendMarketStatusData", async (data) =>
{
MarketData = new List<Market>();
foreach (var item in data)
{
Console.WriteLine($"Company Name: {item.CompanyName}, Volumn: {item.Volume}");
xSource.Add(item.CompanyName);
ySource.Add(item.Volume);
}
source.Add(ySource);
source.Add(xSource);
MarketData = data;
StateHasChanged();
await js.InvokeAsync<object>(chartType, source.ToArray());
xSource.Clear();
ySource.Clear();
});
}
private void ReceivedMarketDataListener()
{
hubConn.On<List<Market>>("CommunicateMarketData", (data) =>
{
MarketReceivedData = data;
StateHasChanged();
});
}
public async Task Dispose()
{
await hubConn.DisposeAsync();
}
async Task generateLineChartTask()
{
MarketDataListener("marketLineChart");
ReceivedMarketDataListener();
await service.GetMarketDataAsync();
}
async Task generateBarChartTask()
{
MarketDataListener("marketBarChart");
ReceivedMarketDataListener();
await service.GetMarketDataAsync();
}
The main difference here is that Blazor Serverside is multithreaded so the callbacks from the circuit will execute on a different Thread.
StateHasChanged() has to be executed on the main (UI) thread so call it like InvokeAsync(StateHasChanged), which is short for InvokeAsync(() => StateHasChanged()).
And be aware of other threading risks. Ie, don't share data like Lists between threads.

Unit test with Moq returns Object reference not set to an instance of an object. when calling method Base.GetAsync()

I am trying to do a unit test with Moq for this method:
public class XsService : EntityResourceService<XModel, string>, IXResourceService<XModel, string>
{
private readonly IXsEntityRepository<XModel, string> XEntityRepository;
Public XsService(
iCorrelationContextAccessor correlationContextAccessor,
IJsonApiContext jsonApiContext,
IXsEntityRepository<XModel, string> XEntityRepository) :
base(jsonApiContext, XEntityRepository)
{
this.XEntityRepository = XEntityRepository;
}
public async Task<IEnumerable<XModel>> GetXsAsync(UModel uModel)
{
await XEntityRepository.GetAllAsync(uModel.UserId);
return await base.GetAsync();
}
}
This is my unit test:
var uModels = new List<UModel>()
{
new UModel { Id = "12341", Name="group_name1" },
new UModel { Id = "12342", Name="group_name1" }
};
[Fact]
public async Task GetUAsync_Ok()
{
//Mocking base class
var baseClassMock = new Mock<XsService>(correlationContextAccessor,
JsonApiContextMock.Object, userGroupsEntityRepositoryMock.Object) { CallBase = true };
baseClassMock.Setup(x => x.GetAsync()).Returns(Task.FromResult(uModels));
// Act
var res = baseClassMock.Object.GetXsAsync(parameter);
// Assert
Assert.Equal("", "");
}
the Error is thrown when reaching the line:
return await base.GetAsync();
Error:
System.NullReferenceException HResult=0x80004003 Message=Object reference not set to an instance of an object. Source=JsonApiDotNetCore StackTrace: at JsonApiDotNetCore.Services.EntityResourceService`3.GetAsyncd__8.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
This exception was originally thrown at this call stack:
JsonApiDotNetCore.Services.EntityResourceServiceTResource, TEntity,
TId.GetAsync()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Maybe I need to moq EntityResourceService, like this:
var eRS = new Mock<EntityResourceService<UModel, string>>(jsonApiContextMock.Object,
userGroupsEntityRepositoryMock.Object, null);
eRS.Setup(x => x.GetAsync()).Returns(Task.FromResult(userGroupModels));
var x = eRS.Object.GetAsync();
But, how can I inject that into the moq when creating the class instance?
This is the GetAsync method code
// MyModelService.cs
public class MyModelService : IResourceService<MyModel>
{
private readonly IMyModelDao _dao;
public MyModelService(IMyModelDao dao)
{
_dao = dao;
}
public Task<IEnumerable<MyModel>> GetAsync()
{
return await _dao.GetModelAsync();
}
}

SignalR + Win RT(Windows 8.1) + using unsigned certificate not working [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
After searching for more than 4 hours, making a Win RT + SignalR work with a selfsigned certificate. Found it! So I share a solution here.
You get the error:
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
The remote certificate is invalid according to the validation procedure.
public class DefaultHttpClientUnsigned : DefaultHttpClient
{
protected override HttpMessageHandler CreateHandler()
{
var filter = new HttpBaseProtocolFilter();
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain);
var handler = new WinRtHttpClientHandler(filter);
return handler;
}
}
Then for creating the connection:
var connection = new HubConnection(address);
var client = new DefaultHttpClientUnsigned();
connection.Start(client);
// https://www.nuget.org/packages/WinRtHttpClientHandler
The source code for the WinRtHttpClientHandler (if it's not available anymore)
public class WinRtHttpClientHandler : HttpMessageHandler
{
private static readonly Version NoVersion = new Version(0, 0);
private static readonly Version Version10 = new Version(1, 0);
private static readonly Version Version11 = new Version(1, 1);
private readonly rt.HttpClient _client;
private bool _disposed = false;
public WinRtHttpClientHandler(IHttpFilter httpFilter)
{
_client = new rt.HttpClient(httpFilter);
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
CheckDisposed();
var rtMessage = await ConvertHttpRequestMessaageToRt(request, cancellationToken).ConfigureAwait(false);
var resp = await _client.SendRequestAsync(rtMessage).AsTask(cancellationToken).ConfigureAwait(false);
var netResp = await ConvertRtResponseMessageToNet(resp, cancellationToken).ConfigureAwait(false);
return netResp;
}
internal static async Task<rt.HttpRequestMessage> ConvertHttpRequestMessaageToRt(HttpRequestMessage message, CancellationToken token)
{
var rt = new rt.HttpRequestMessage()
{
Method = new rt.HttpMethod(message.Method.Method),
Content = await GetContentFromNet(message.Content).ConfigureAwait(false),
RequestUri = message.RequestUri,
};
CopyHeaders(message.Headers, rt.Headers);
foreach (var prop in message.Properties)
rt.Properties.Add(prop);
return rt;
}
internal static async Task<HttpRequestMessage> ConvertRtRequestMessageToNet(rt.HttpRequestMessage message, CancellationToken token)
{
var req = new HttpRequestMessage()
{
Method = new HttpMethod(message.Method.Method),
RequestUri = message.RequestUri,
Content = await GetNetContentFromRt(message.Content, token).ConfigureAwait(false),
};
foreach (var header in message.Headers)
req.Headers.TryAddWithoutValidation(header.Key, header.Value);
foreach (var prop in message.Properties)
req.Properties.Add(prop);
return req;
}
internal static void CopyHeaders(IEnumerable<KeyValuePair<string, IEnumerable<string>>> source, IDictionary<string, string> destination)
{
var headers = from kvp in source
from val in kvp.Value
select new KeyValuePair<string, string>(kvp.Key, val);
foreach (var header in headers)
destination.Add(header);
}
internal static async Task<rt.IHttpContent> GetContentFromNet(HttpContent content)
{
if (content == null)
return null;
var stream = await content.ReadAsStreamAsync().ConfigureAwait(false);
var c = new rt.HttpStreamContent(stream.AsInputStream());
CopyHeaders(content.Headers, c.Headers);
return c;
}
internal static async Task<HttpContent> GetNetContentFromRt(rt.IHttpContent content, CancellationToken token)
{
if (content == null)
return null;
var str = await content.ReadAsInputStreamAsync().AsTask(token).ConfigureAwait(false);
var c = new StreamContent(str.AsStreamForRead());
foreach (var header in content.Headers)
c.Headers.TryAddWithoutValidation(header.Key, header.Value);
return c;
}
internal static async Task<HttpResponseMessage> ConvertRtResponseMessageToNet(rt.HttpResponseMessage message, CancellationToken token)
{
var resp = new HttpResponseMessage((HttpStatusCode)(int)message.StatusCode)
{
ReasonPhrase = message.ReasonPhrase,
RequestMessage = await ConvertRtRequestMessageToNet(message.RequestMessage, token).ConfigureAwait(false),
Content = await GetNetContentFromRt(message.Content, token).ConfigureAwait(false),
Version = GetVersionFromEnum(message.Version),
};
foreach (var header in message.Headers)
resp.Headers.TryAddWithoutValidation(header.Key, header.Value);
return resp;
}
internal static Version GetVersionFromEnum(rt.HttpVersion version)
{
switch (version)
{
case rt.HttpVersion.None:
return NoVersion;
break;
case rt.HttpVersion.Http10:
return Version10;
break;
case rt.HttpVersion.Http11:
return Version11;
break;
default:
throw new ArgumentOutOfRangeException("version");
}
}
private void CheckDisposed()
{
if (_disposed)
throw new ObjectDisposedException("WinRtHttpClientHandler");
}
protected override void Dispose(bool disposing)
{
if (disposing && !_disposed)
{
_client.Dispose();
_disposed = true;
}
base.Dispose(disposing);
}
}
Hope this helps some people out there.

How can I properly localize Razor Views in ServiceStack

I am currently getting the prefered Culture from the Accept-Language-HTTP-Header and storing it in the AuthUserSession.
In AppHost.Configure:
PreRequestFilters.Add((httpReq, httpResp) =>
{
var session = httpReq.GetSession();
if (session is AuthUserSession)
{
var auths = ((AuthUserSession)session);
if (auths.Culture == null)
{
//parse languages
var languages = httpReq.Headers["Accept-Language"];
//auths.Culture = Helpers.CultureHelper.GetBestAcceptLanguageMatch(languages);
auths.Culture = "en-US";
httpReq.SaveSession(session, new TimeSpan(0, 20, 0));
}
}
});
My current solution to Render a View in the users prefered Culture is to change the current Threads UICulture from the Razor view:
#inherits ViewPage<LandingPage.ServiceModel.Operations.AskQuestions>
#{
var session = GetSession<ServiceStack.ServiceInterface.Auth.AuthUserSession>();
var prevCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(session.Culture);
//access a Resource
ViewBag.Title = Resources.AskTitle;
}
Views Content
#{
System.Threading.Thread.CurrentThread.CurrentUICulture = prevCulture;
}
This seems unelegant and clumsy. What would be a better way to do this?
*edit:
I am looking for two hook points: one just before the View gets called, and one right after it got rendered. These should keep the interference with other Requests that get served to zero.
I discovered today that a custom IServiceRunner supplies just the right hooks (see https://github.com/ServiceStack/ServiceStack/wiki/Customize-HTTP-Responses).
As the one above it only works, when the page is served by a Service, because the RequestFilters and the ServiceRunner are not even touched when a ContentPage is requested.
It might be of interest, that the RequestFilter is another hook point, that is called before the Execution of the View. But the same seems true for the ResponseFilter. A small test in which I tried to reset the CurrentUICulture in the ResponseFilter rendered my page unlocalized.
In AppHost
public override void Configure(Funq.Container container)
{
//plugins
Plugins.Add(new RazorFormat());
Plugins.Add(new AuthFeature(() =>
new AuthUserSession(),
new IAuthProvider[] {
new BasicAuthProvider()
}));
//request filters
PreRequestFilters.Add((httpReq, httpResp) =>
{
var session = httpReq.GetSession();
if (session is AuthUserSession)
{
var auths = ((AuthUserSession)session);
if (auths.Culture == null)
{
var languages = httpReq.Headers["Accept-Language"];
auths.Culture = Helpers.CultureHelper.GetBestAcceptLanguageMatch(languages);
httpReq.SaveSession(session, new TimeSpan(0, 20, 0));
}
httpReq.SetItem("Culture", auths.Culture);
}
});
//funq
var userRep = new InMemoryAuthRepository();
container.Register<IUserAuthRepository>(userRep);
container.Register<ICacheClient>(c => new MemoryCacheClient());
}
//use a custom IServiceRunner
public override ServiceStack.ServiceHost.IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext)
{
var runner = base.CreateServiceRunner<TRequest>(actionContext);
return new CultureAwareServiceRunner<TRequest>(this, actionContext);
}
CultureAwareServiceRunner.cs
public class CultureAwareServiceRunner<T> : ServiceRunner<T>
{
public CultureAwareServiceRunner(AppHost appHost, ServiceStack.WebHost.Endpoints.ActionContext actionContext) :
base(appHost, actionContext)
{ }
public override void OnBeforeExecute(IRequestContext requestContext, T request)
{
var httpReq = requestContext.Get<IHttpRequest>();
httpReq.SetItem("PreviousCulture", Thread.CurrentThread.CurrentUICulture);
string culture = httpReq.GetItem("Culture") as string;
if (culture != null)
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
base.OnBeforeExecute(requestContext, request);
}
public override object OnAfterExecute(IRequestContext requestContext, object response)
{
var httpReq = requestContext.Get<IHttpRequest>();
var prevCulture = httpReq.GetItem("PreviousCultureCulture") as CultureInfo;
if (prevCulture != null)
Thread.CurrentThread.CurrentUICulture = prevCulture;
return base.OnAfterExecute(requestContext, response);
}
}

Why does adding a constructor fail this MSpec test with System.InvalidOperationException?

I have this first version of a class
public class GenerateAuthorisationWorkflows : IGenerateAuthorisationWorkflows
{
public IList<Guid> FromDtaObjects(IList<DtaObject> dtaObjects, Employee requestingEmployee)
{
foreach (var dtaObject in dtaObjects) { }
return new List<Guid>();
}
public IList<Guid> FromDtaObjects()
{
return new List<Guid>();
}
}
And the MSpec tests for it
public abstract class specification_for_generate_workflows : Specification<GenerateAuthorisationWorkflows>
{
protected static IWorkflowService workflowService;
Establish context = () => { workflowService = DependencyOf<IWorkflowService>(); };
}
[Subject(typeof(GenerateAuthorisationWorkflows))]
public class when_generate_workflows_is_called_with_a_dta_object_list_and_an_employee : specification_for_generate_workflows
{
static IList<Guid> result;
static IList<DtaObject> dtaObjects;
static Employee requestingEmployee;
Establish context = () =>
{
var mocks = new MockRepository();
var stubDtaObject1 = mocks.Stub<DtaObject>();
var stubDtaObject2 = mocks.Stub<DtaObject>();
var dtaObjectEnum = new List<DtaObject>{stubDtaObject1,stubDtaObject2}.GetEnumerator();
dtaObjects = mocks.Stub<IList<DtaObject>>();
dtaObjects.Stub(x => x.GetEnumerator()).Return(dtaObjectEnum).WhenCalled(x => x.ReturnValue = dtaObjectEnum);
requestingEmployee = mocks.Stub<Employee>();
mocks.ReplayAll();
};
Because of = () => result = subject.FromDtaObjects(dtaObjects, requestingEmployee);
It should_enumerate_the_dta_objects = () => dtaObjects.received(x=> x.GetEnumerator());
It should_call_workflow_host_helper = () => workflowService.AssertWasCalled(x => x.StartWorkflow());
}
With this configuration, my first test passes and my second test fails, as expected. I added a constructor to the class to inject the IWorkflowService.
public class GenerateAuthorisationWorkflows : IGenerateAuthorisationWorkflows
{
IWorkflowService _workflowService;
GenerateAuthorisationWorkflows(IWorkflowService workflowService)
{
_workflowService = workflowService;
}
public IList<Guid> FromDtaObjects(IList<DtaObject> dtaObjects, Employee requestingEmployee)
{
foreach (var dtaObject in dtaObjects)
{
Guid workflowKey = _workflowService.StartWorkflow();
}
return new List<Guid>();
}
public IList<Guid> FromDtaObjects()
{
return new List<Guid>();
}
}
Now, when I run the tests, they fail at the Because:
System.InvalidOperationException: Sequence contains no elements
at System.Linq.Enumerable.First(IEnumerable`1 source)
at MSpecTests.EmployeeRequestSystem.Tasks.Workflows.when_generate_workflows_is_called_with_a_dta_object_list_and_an_employee.<.ctor>b__4() in GenerateAuthorisationWorkflowsSpecs.cs: line 76
For clarity, line 76 above is:
Because of = () => result = subject.FromDtaObjects(dtaObjects, requestingEmployee);
I've tried tracing the problem but am having no luck. I have tried setting up a constructor that takes no arguments but it raises the same error. I have similar classes with IoC dependencies that work fine using MSpec/Rhino Mocks, where am I going wrong?
Castle Windsor requires a public constructor to instantiate a class. Adding public to the constructor allows correct operation.
public class GenerateAuthorisationWorkflows : IGenerateAuthorisationWorkflows
{
IWorkflowService _workflowService;
public GenerateAuthorisationWorkflows(IWorkflowService workflowService)
{
_workflowService = workflowService;
}
public IList<Guid> FromDtaObjects(IList<DtaObject> dtaObjects, Employee requestingEmployee)
{
foreach (var dtaObject in dtaObjects)
{
Guid workflowKey = _workflowService.StartWorkflow();
}
return new List<Guid>();
}
public IList<Guid> FromDtaObjects()
{
return new List<Guid>();
}
}
Rowan, looks like you answered your own question. It's good practice to explicitly state the access modifiers! By default, C# chooses private. These kinds of errors are easy to miss!
I can also see that your Establish block is too complicated. You're testing the implementation details and not the behavior. For example, you are
stubbing the GetEnumerator call that's implicitly made inside the foreach loop.
asserting that the workflow service was called only once
mixing MSpec automocking and your own local mocks
You're not actually testing that you got a GUID for every object in the input list. If I were you, I'd test the behavior like this...
public class GenerateAuthorisationWorkflows : IGenerateAuthorisationWorkflows
{
private readonly IWorkflowService _service;
public GenerateAuthorisationWorkflows(IWorkflowService service)
{
_service = service;
}
public List<Guid> FromDtaObjects(List<DtaObject> input, Employee requestor)
{
// I assume that the workflow service generates a new key
// per input object. So, let's pretend the call looks like
// this. Also using some LINQ to avoid the foreach or
// building up a local list.
input.Select(x => _service.StartWorkflow(requestor, x)).ToList();
}
}
[Subject(typeof(GenerateAuthorisationWorkflows))]
public class When_generating_authorisation_keys_for_this_input
: Specification<GenerateAuthorisationWorkflows>
{
private static IWorkflowService _service;
private static Employee _requestor = new Employee();
private static List<DtaObject> _input = new List<DtaObject>()
{
new DtaObject(),
new DtaObject(),
};
private static List<Guid> _expected = new List<Guid>()
{
Guid.NewGuid(),
Guid.NewGuid(),
};
private static List<Guid> _actual = new List<Guid>();
Establish context = () =>
{
// LINQ that takes each item from each list in a pair. So
// the service is stubbed to return a specific GUID per
// input DtaObject.
_input.Zip(_expected, (input, output) =>
{
DependencyOf<IWorkflowService>().Stub(x => x.StartWorkflow(_requestor, input)).Return(output);
});
};
Because of = () => _actual = Subject.FromDtaObjects(_input, _requestor);
// This should be an MSpec collection assertion that
// ensures that the contents of the collections are
// equivalent
It should_get_a_unique_key_per_input = _actual.ShouldEqual(_expected);
}