Is there a way to run NRule Engine in asyncronously? - nrules

I want to run all rules asyncronously to make it thread safe
When i m performing load test then why RuleEngine taking so much time to execute all rules.
NRuleRepository repository = null;
foreach (var rule in rules)
{
repository = new NRuleRepository();
repository.LoadRules(rule.Rule);
var factory = repository.Compile();
var session = factory.CreateSession();
NRuleBody data = null;
foreach (var fact in rule.RuleDataList)
{
data = new NRuleBody();
data.Rule = rule.Rule;
data.RuleData = fact;
session.Insert(data);
}
result += session.Fire();
}
Can i make call as below:
session.FireAsync();
or there is any other option to fire Multiple rules but in async ?
and NRuleRepository class should be reinitialize on every request ?

At the very least, you could probably utilise Task.Run() in order to create a thread for each instance of the repository, but what you're doing seems very inefficient.
Why are you inserting the rule with the data in the session? You've already added the rule to the repository.
If you are only ever having a singular rule in the repository, NRules is almost certainly overkill, and you would be better placed doing almost anything else.

Related

Recommended way to test Scheduler/Throttle

I'm in the process of rewriting one little WPF-App I wrote to make use of ReactiveUI, to get a feeling about the library.
I really like it so far!
Now I've stumbled upon the Throttle method and want to use it when applying a filter to a collection.
This is my ViewModel:
namespace ReactiveUIThrottle
{
public class MainViewModel : ReactiveObject
{
private string _filter;
public string Filter { get => _filter; set => this.RaiseAndSetIfChanged(ref _filter, value); }
private readonly ReactiveList<Person> _persons = new ReactiveList<Person>();
private readonly ObservableAsPropertyHelper<IReactiveDerivedList<Person>> _filteredPersons;
public IReactiveDerivedList<Person> Persons => _filteredPersons.Value;
public MainViewModel()
{
Filter = string.Empty;
_persons.AddRange(new[]
{
new Person("Peter"),
new Person("Jane"),
new Person("Jon"),
new Person("Marc"),
new Person("Heinz")
});
var filterPersonsCommand = ReactiveCommand.CreateFromTask<string, IReactiveDerivedList<Person>>(FilterPersons);
this.WhenAnyValue(x => x.Filter)
// to see the problem
.Throttle(TimeSpan.FromMilliseconds(2000), RxApp.MainThreadScheduler)
.InvokeCommand(filterPersonsCommand);
_filteredPersons = filterPersonsCommand.ToProperty(this, vm => vm.Persons, _persons.CreateDerivedCollection(p => p));
}
private async Task<IReactiveDerivedList<Person>> FilterPersons(string filter)
{
await Task.Delay(500); // Lets say this takes some time
return _persons.CreateDerivedCollection(p => p, p => p.Name.Contains(filter));
}
}
}
The filtering itself works like a charm, also the throttling, when using the GUI.
However, I'd like to unittest the behavior of the filtering and this is my first attempt:
[Test]
public void FilterPersonsByName()
{
var sut = new MainViewModel();
sut.Persons.Should().HaveCount(5);
sut.Filter = "J";
sut.Persons.Should().HaveCount(2);
}
This test fails because the collection still has 5 people.
When I get rid of the await Task.Delay(500) in FilterPersons then the test will pass, but takes 2 seconds (from the throttle).
1) Is there a way to have the throttle be instant within the test to speed up the unittest?
2) How would I test the async behavior in my filter?
I'm using ReactiveUI 7.x
Short answers:
Yes, by making sure you're using CurrentThreadScheduler.Instance when running under test
Instead of using CurrentThreadScheduler, use a TestScheduler and manually advance it
The longer answer is that you need to ensure your unit tests can control the scheduler being used by your System Under Test (SUT). By default, you'll generally want to use CurrentThreadScheduler.Instance to make things happen "instantly" without any need to advance the scheduler manually. But when you want to write tests that do validate timing, you use a TestScheduler instead.
If, as you seem to be, you're using RxApp.*Scheduler, take a look at the With extension method, which can be used like this:
(new TestScheduler()).With(sched => {
// write test logic here, and RxApp.*Scheduler will resolve to the chosen TestScheduler
});
I tend to avoid using the RxApp ambient context altogether for the same reason I avoid all ambient contexts: they're shared state and can cause trouble as a consequence. Instead, I inject an IScheduler (or two) into my SUT as a dependency.

Time-based cache for REST client using RxJs 5 in Angular2

I'm new to ReactiveX/RxJs and I'm wondering if my use-case is feasible smoothly with RxJs, preferably with a combination of built-in operators. Here's what I want to achieve:
I have an Angular2 application that communicates with a REST API. Different parts of the application need to access the same information at different times. To avoid hammering the servers by firing the same request over and over, I'd like to add client-side caching. The caching should happen in a service layer, where the network calls are actually made. This service layer then just hands out Observables. The caching must be transparent to the rest of the application: it should only be aware of Observables, not the caching.
So initially, a particular piece of information from the REST API should be retrieved only once per, let's say, 60 seconds, even if there's a dozen components requesting this information from the service within those 60 seconds. Each subscriber must be given the (single) last value from the Observable upon subscription.
Currently, I managed to achieve exactly that with an approach like this:
public getInformation(): Observable<Information> {
if (!this.information) {
this.information = this.restService.get('/information/')
.cache(1, 60000);
}
return this.information;
}
In this example, restService.get(...) performs the actual network call and returns an Observable, much like Angular's http Service.
The problem with this approach is refreshing the cache: While it makes sure the network call is executed exactly once, and that the cached value will no longer be pushed to new subscribers after 60 seconds, it doesn't re-execute the initial request after the cache expires. So subscriptions that occur after the 60sec cache will not be given any value from the Observable.
Would it be possible to re-execute the initial request if a new subscription happens after the cache timed out, and to re-cache the new value for 60sec again?
As a bonus: it would be even cooler if existing subscriptions (e.g. those who initiated the first network call) would get the refreshed value whose fetching had been initiated by the newer subscription, so that once the information is refreshed, it is immediately passed through the whole Observable-aware application.
I figured out a solution to achieve exactly what I was looking for. It might go against ReactiveX nomenclature and best practices, but technically, it does exactly what I want it to. That being said, if someone still finds a way to achieve the same with just built-in operators, I'll be happy to accept a better answer.
So basically since I need a way to re-trigger the network call upon subscription (no polling, no timer), I looked at how the ReplaySubject is implemented and even used it as my base class. I then created a callback-based class RefreshingReplaySubject (naming improvements welcome!). Here it is:
export class RefreshingReplaySubject<T> extends ReplaySubject<T> {
private providerCallback: () => Observable<T>;
private lastProviderTrigger: number;
private windowTime;
constructor(providerCallback: () => Observable<T>, windowTime?: number) {
// Cache exactly 1 item forever in the ReplaySubject
super(1);
this.windowTime = windowTime || 60000;
this.lastProviderTrigger = 0;
this.providerCallback = providerCallback;
}
protected _subscribe(subscriber: Subscriber<T>): Subscription {
// Hook into the subscribe method to trigger refreshing
this._triggerProviderIfRequired();
return super._subscribe(subscriber);
}
protected _triggerProviderIfRequired() {
let now = this._getNow();
if ((now - this.lastProviderTrigger) > this.windowTime) {
// Data considered stale, provider triggering required...
this.lastProviderTrigger = now;
this.providerCallback().first().subscribe((t: T) => this.next(t));
}
}
}
And here is the resulting usage:
public getInformation(): Observable<Information> {
if (!this.information) {
this.information = new RefreshingReplaySubject(
() => this.restService.get('/information/'),
60000
);
}
return this.information;
}
To implement this, you will need to create your own observable with custom logic on subscribtion:
function createTimedCache(doRequest, expireTime) {
let lastCallTime = 0;
let lastResult = null;
const result$ = new Rx.Subject();
return Rx.Observable.create(observer => {
const time = Date.now();
if (time - lastCallTime < expireTime) {
return (lastResult
// when result already received
? result$.startWith(lastResult)
// still waiting for result
: result$
).subscribe(observer);
}
const disposable = result$.subscribe(observer);
lastCallTime = time;
lastResult = null;
doRequest()
.do(result => {
lastResult = result;
})
.subscribe(v => result$.next(v), e => result$.error(e));
return disposable;
});
}
and resulting usage would be following:
this.information = createTimedCache(
() => this.restService.get('/information/'),
60000
);
usage example: https://jsbin.com/hutikesoqa/edit?js,console

Can you record accessed methods in Visual Studio?

I'm retroactively documenting and writing unit tests for some C# code. I would like to determine what code is actually being used and when.
In Visual Studio 2012, is there a way to record all the methods accessed and in what order while walking through specific scenarios?
You could run your application with a profiler attached, which will give you all accessed methods, call chains, counts, etc.
The Visual Studio Profiler will give you the time spent in each method, and let you inspect the call heirarchy. I don't know if it will give you the exact order they were called in though.
EDIT: Apparently attaching the profiler to a running unit test is harder in VS2012.
Are you wanting to execute a test method that make sure that a particular method on a class was invoked ? If so i dont know of a way to do it in VS alone, but you can use a mock framework to create dependency mocks and check values on them. Here is a snippet of a unit test:
[TestMethod]
public void HttpPostPrivacyPolicyFacadeSvcErrorTest()
{
var controller = ControllerHelper.GetRouteController();
controller.Session[SessionVariable.User] = new UserInfo() { UserName = Config.Data.Username };
var idmSvcMock = new Mock<IUserServiceDAO>();
var facadeSvcMock = new Mock<IFacadeSvcDAO>();
//setup the facade mock to throw exception to simulate FacadeServiceException
facadeSvcMock.Setup(x => x.SetPrivacyAcceptanceStatus(It.IsAny<UserInfo>())).Throws<Exception>();
var userCollectorMock = new Mock<IUserInfoCollector>();
userCollectorMock.Setup(x => x.GetUserInfo()).Returns(new UserInfo() { UserName = Config.Data.Username });
controller.FacadeSvc = facadeSvcMock.Object;
controller.UserServiceDAO = idmSvcMock.Object;
controller.UserCollector = userCollectorMock.Object;
controller.DefaultErrorId = "Route_errors_Unabletoprocess";
//action
var res = controller.Privacy(new FormCollection());
//assert
//make sure we go to the right controller, action, with the correct params.
res.AssertActionRedirect().ToController("Errors").ToAction("Index").WithParameter("id", "Route_errors_Unabletoprocess");
//did we call setprivacy once on the mock?
facadeSvcMock.Verify(x => x.SetPrivacyAcceptanceStatus(It.IsAny<UserInfo>()), Times.Exactly(1));
In the test above i check that SetPrivacyAcceptance was invoked once and only once on my facadeSvcMock instance. More on moq here: Moq
this block of code is actually checking how many times SetPrivacyAcceptanceStatus was invoked:
//did we call setprivacy once on the mock?
facadeSvcMock.Verify(x => x.SetPrivacyAcceptanceStatus(It.IsAny()), Times.Exactly(1));
the It.IsAny() is the one parameter to that method, so the line above says basically "For any input parameter of type UserInfo verify that we invoked SetPrivacyAcceptanceStatus exactly once."

linq query trouble

Below is the code where I try to do a simple Linq-to-entities framework query, and I want to also access the results one by one:
inctDomainContext innn = new inctDomainContext();
var exx = from c in innn.cordonnes select c;
foreach (var i in exx) {
//doing something here but the programe doesn't enter the loop
}
Why doesn't the program enter into foreach loop?
it appears you're working with WCF Ria Services in Silverlight. This is totally different from how things work when using EntityFramework directly. In your case, you have to "load" the data, before being able to access it.
To do this, you have to call the "Load" method on the domain context and pass in the query you need (in your case GetCoordonneQuery()), and then you can pass a callback to be executed when the load asynchronous call is finished. The callback will have access to the results of the query. Here's an example:
....
context.Load(GetCoordonneQuery(),OnLoadCoordonneCompleted,null)
....
void OnLoadCoordonneCompleted(LoadOperation<Coordonne> loadOp)
{
foreach(var coordonne in loadOp.Entities)
{
//do something with the data
}
}
when the OnLoadCoordonneCompleted is called (i.e: when the asynchronous load call is finished), the context.Coordonnes will be loaded and contain the data you want.
Hope this helps
Are you sure there is data in there?
Try this:
inctDomainContext innn = new inctDomainContext();
bool exxAny = innn.cordonnes.Any();
Then if exxAny is false, there is no data in the collection and hence, the foreach does nothing.

How work with AsyncController in asp.net MVC 3?

Search several blogs about it but always are same examples.
I dunno if misunderstood or'm not knowing use but see no parallel process when work with AsyncController.
The following tests performed
Create a new project of type Asp.net MVC
HomeController.cs
public void IndexAsync()
{
AsyncManager.OutstandingOperations.Increment();
var bg = new BackgroundWorker();
bg.DoWork += (o, e) => GetEntriesBlog();
bg.RunWorkerCompleted += (o, e) =>
{
AsyncManager.Parameters["items"] = e.Result;
AsyncManager.OutstandingOperations.Decrement();
};
bg.RunWorkerAsync();
ViewBag.Message = "Modify this template to kick-start your ASP.NET MVC application.";
}
public ActionResult IndexCompleted(IEnumerable<SyndicationItem> items)
{
return View(items);
}
[NonAction]
public IEnumerable<SyndicationItem> GetEntriesBlog(int page = 0)
{
using (var reader = XmlReader.Create("http://blog.bindsolution.com/rss"))
{
Thread.Sleep(20000);
var rssData = SyndicationFeed.Load(reader);
if (rssData != null)
{
return (from item in rssData.Items
orderby item.PublishDate descending
select item).Take(3).Skip(3 * page).ToList();
}
return null;
}
}
Always delay 20 seconds browsing the site!
I was thinking of using PartialView AsyncController in to perform this task. Work?
I think you are misunderstanding what the Asynchronous Background worker would do.
If the operation takes 20 seconds using a background worker will not reduce that time or make the view render any faster. Using an asynchronous operations will free up the worker process on the server to process other requests while this long running request keep chugging along.
In your case I think you should create a very simple view that returns quickly to the user and kick of the long running operation as an asynch request from the client. For example, render the fast portions of your page (e.g. header, menus, et cetera) and make an AJAX request for the blog entries.
Depending on the nature of the code in GetEntriesBlog you might not need to make the controller operation asynchronous. In theory, since most of the time in this method will be spend waiting for the HTTP GET request to http://blog.bindsolution.com/rss to complete, it might be a good idea but in practice those things need to be bench marked (and perhaps under heavy load) to make sure you are getting the benefit that you expect. Keep in mind that your server code side will be more complex (and harder to maintain) if you make it asynch. I would suggest you go this route only if you do get a significant benefit.

Resources