I am trying to split load over more than one akka actor system.
Unfortunately the round robin group in not forwarding messages to remote workers. I can see that actor is activated, but there is no work done.
the full code is on github
Is there any other setting that I could miss in my configuration?
private void CreateRemoteCrawlerGroup()
{
var hostname = "374110044f24";
var hostname2 = "25b360699a27";
var remoteAddress2 = Address.Parse($"akka.tcp://DeployTarget#{hostname2}:8090");
var remoteScope2 = new RemoteScope(remoteAddress2);
var remoteCrawler1 =
Context.ActorOf(
Props.Create(() => new WebCrawlerActor(new AppSettingsConfiguration(), Self))
.WithRouter(new RoundRobinPool(2)) // new DefaultResizer(1, 2, messagesPerResize: 500)
.WithDispatcher("my-dispatcher")
.WithDeploy(Deploy.None.WithScope(remoteScope2)), "a");
var remoteAddress = Address.Parse($"akka.tcp://DeployTarget#{hostname}:8090");
var remoteScope = new RemoteScope(remoteAddress);
var remoteCrawler2 =
Context.ActorOf(
Props.Create(() => new WebCrawlerActor(new AppSettingsConfiguration(), Self))
.WithRouter(new RoundRobinPool(2)) // new DefaultResizer(1, 2, messagesPerResize: 500)
.WithDispatcher("my-dispatcher")
.WithDeploy(Deploy.None.WithScope(remoteScope)), "remoteCrawler01");
var workers = new List<string> { remoteCrawler1.Path.ToString(), remoteCrawler2.Path.ToString() };
var router = Context.ActorOf(Props.Empty.WithRouter(new RoundRobinGroup(workers)), "some-group");
_actorDictionary.Add("WebCrawlerActor", router);
}
the solution was switch to akka cluster and use clustr pool instead
var remoteEcho2 =
Context.ActorOf(
Props.Create(() => new WebCrawlerActor(new AppSettingsConfiguration(), Self))
.WithRouter(new ClusterRouterPool(new RoundRobinPool(5), new ClusterRouterPoolSettings(5, 1, true, "crawler"))), "WebCrawlerActor2a");
_actorDictionary.Add("WebCrawlerActor", remoteEcho2);
Related
I am working on a project with Vue and Leaflet that for now just shows a map and I want that when you give the start and end coordinates it colours the route from between those points (or many points and a route than goes through all of them). Unfortunately, I found that the plugin for Leaflet that uses OSRM for automating routing "will not work unless you configure a routing backend yourself". Is there an alternative to that? Any other open-source plugin for Vue Leaflet (or alternatively for OpenLayers(VueLayers) that can auto-track existing routes? Thank you in advance.
You could interface Openlayers directly with a service such as OpenRouteService https://openrouteservice.org/dev/#/api-docs/v2/directions/{profile}/json/post This code assumes a map routesMap with a vector layer orsRoute, and array routeComplete of coordinate pairs in view projection for start, optional waypoint, and end, and API key orsKey
var viewProj = routesMap.getView().getProjection();
var startA = ol.proj.transform(routeComplete[0], viewProj, 'EPSG:4326');
var viaA = routeComplete[1] ? ol.proj.transform(routeComplete[1], viewProj, 'EPSG:4326') : null;
var endA = ol.proj.transform(routeComplete[2], viewProj, 'EPSG:4326');
var startN = startA.toString();
var viaN = viaA ? viaA.toString() : null;
var endN = endA.toString();
var url = 'https://api.openrouteservice.org/v2/directions/driving-car/json';
var params = '{"coordinates":[[' + startN + '],[' + (viaN ? viaN + '],[' : '') + endN + ']]}';
var orsXhr = new XMLHttpRequest();
orsXhr.onreadystatechange = function() {
if (orsXhr.readyState == 4) {
if (orsXhr.status == 200) {
var route = JSON.parse(orsXhr.responseText).routes[0];
var linestring = route.geometry;
var distance = route.summary.distance;
var duration = route.summary.duration;
orsRoute.getSource().addFeature(
new ol.Feature({
geometry: new ol.format.Polyline().readGeometry(linestring).transform('EPSG:4326', viewProj),
name: 'Openrouteservice',
distance: distance,
duration: duration
})
);
orsRoute.getSource().setAttributions('© Powered by openrouteservice');
}
}
}
orsXhr.onerror = function(e) { console.log('error'); }
orsXhr.ontimeout = function(e) { console.log('timeout'); }
orsXhr.open('POST', url, true);
orsXhr.timeout = 3000;
orsXhr.setRequestHeader('Content-type', 'application/json');
orsXhr.setRequestHeader('Authorization', orsKey);
orsXhr.send(params);
I have 3 applications pointing to single redis endpoint. I want to use separate redis database per application. But when I am trying to set defaultDatabase to 1 or 2 in ConfigurationOption it is still using database 0. I am using stackexchange redis. Code is as given below :
var configurationOptions = new ConfigurationOptions
{
EndPoints = { "myredis.redis.cache.windows.net" },
Password = "xxxxxxxxxxxxxxxxxxx",
Ssl = true,
ConfigurationChannel = "MyRedis",
ChannelPrefix = "MR",
DefaultDatabase = 1,
};
var connectionMultiplexer = ConnectionMultiplexer.Connect(configurationOptions);
var cacheClient = new StackExchangeRedisCacheClient(connectionMultiplexer, new JilSerializer(), database: 1);
Now adding new key to cache using ICacheClient
var user = new User()
{
Id = 100,
Name = "John Doe"
};
var response = cacheClient.Add("mykey", user);
Then retrieving added key from cache
var addedUser= cacheClient.Get<string>("mykey");
Is there anything I am doing wrong? Ideally as per stated in configuration options it should store keys to db1 but it is storing to db0 instead.
When you retrieve the database object, you should specify the database number. https://stackexchange.github.io/StackExchange.Redis/Basics.html#using-a-redis-database
I've used IdentityServer4 with asp net core Web, all works fine when debug in localhost:50481, but when I use myipaddress:50481 on the same computer and debug mode, it failed. I do not use a temporary credential, instead, I created a RSA cert:
.AddSigningCredential(Config.GetSigningCertificate())
public static RsaSecurityKey GetSigningCertificate()
{
var filename = Path.Combine(Directory.GetCurrentDirectory(), "certificateKey.rsa");
if (File.Exists(filename))
{
var keyFile = File.ReadAllText(filename);
var tempKey = JsonConvert.DeserializeObject<TemporaryRsaKey>(keyFile, new JsonSerializerSettings() { ContractResolver = new RsaKeyContractResolver() });
return CreateRsaSecurityKey(tempKey.Parameters, tempKey.KeyId);
}
else
{
var key = CreateRsaSecurityKey();
RSAParameters parameters;
if (key.Rsa != null)
parameters = key.Rsa.ExportParameters(includePrivateParameters: true);
else
parameters = key.Parameters;
var tempKey = new TemporaryRsaKey
{
Parameters = parameters,
KeyId = key.KeyId
};
File.WriteAllText(filename, JsonConvert.SerializeObject(tempKey, new JsonSerializerSettings() { ContractResolver = new RsaKeyContractResolver() }));
return CreateRsaSecurityKey(tempKey.Parameters, tempKey.KeyId);
}
}
I also checked the jwks of localhost and ipaddress, they are matched.
When I publish the project to local IIS, localhost does not work too, present a 500 Internal error.
all the url in my app is "http://localhost:50481"
I have to say this is a stupid mistake, I have not notice the authConfig,
let config;
if (window.location.hostname === 'localhost') {
config = configForDevelopment;
} else {
config = configForProduction;
}
when I use ip address, the config is switch to prod, change localhost to my ip address make sense.
hope it could others.
I created a WCF data service which return JSON format
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
i used titanium to connect to web service to get data
var label= Titanium.UI.createLabel({
top:300
});
var data = [];
// Connecting to WCF data service
var xhr = Titanium.Network.createHTTPClient();
var theURL = 'http://localhost:4338/DataService.svc/Orders?$format=json';
var json;
xhr.onload = function (){
var json = JSON.parse(this.responseText);
};
for (var i = 0 ; i < json.length; i++)
{
data.push(json[i]);
}
label.text = data[0].OrderID;
xhr.open('Get',theURL);
what is wrong
First of all you have to be aware that HTTP requests are asynchchronous, which means although it will take some time to fetch the response (depending on the internet connection, server speed, data size etc.), the succeeding code is executed. If the request was synchronous, it would block the app and any user interaction while it loads. That is why the client provides callbacks that are fired on certain state changes.
Your code
var data = [];
// Connecting to WCF data service
var xhr = Titanium.Network.createHTTPClient();
// Just guessing, but is the $ necessary?
var theURL = 'http://localhost:4338/DataService.svc/Orders?$format=json';
// You are defining json here 'globally'
var json;
xhr.onload = function (){
// You are defining the json variable within the scope of
// the onload function, so it can't be accessed from outside
// the function. Moreover, you are overwriting json of the global scope
// within this function
var json = JSON.parse(this.responseText);
};
// At this point, json is undefined
// Moreover, this code is executed before xhr.onload fires
for (var i = 0 ; i < json.length; i++)
{
data.push(json[i]);
}
label.text = data[0].OrderID;
// Method should be GET not Get
xhr.open('Get',theURL);
How it should work
var data = [];
var theURL = 'http://localhost:4338/DataService.svc/Orders?format=json';
var xhr = Titanium.Network.createHTTPClient();
xhr.onload = function (){
// Assuming that you have a valid json response
var json = JSON.parse(this.responseText);
for (var i=0; i < json.length; i++) {
data.push(json[i]);
}
// For testing, otherwise make sure it won't break if your response is empty
label.text = data[0].OrderID;
};
xhr.open('GET', theURL);
I am generating the knockout mapping from server side view model using below
var bindData2ViewModel = function (data) {
var rdata = ko.toJSON(data);
ko.mapping.fromJSON(rdata, {}, vm.model());
ko.applyBindings(vm);
};
var CustomerViewModel = function () {
var self = this;
self.model = ko.observable({});
return { model: self.model };
};
var vm = new CustomerViewModel();
now there is another call which is giving me the data... i just want to bind that data to the client side viewmodel without changing the binding... how to do that?
var rebindData2ViewModel = function (data) {
var rdata = ko.toJSON(data);
vm.model.set(rdata);
ko.applyBindings(vm);
};
tried above but not working... what is the correct way to do this?
basically to rebind the data to the existing model.. you just need to set the data using the angular brackets.. no need of json etc... because data should itself return as jsonresult
var rebindData2ViewModel = function (data) {
vm.model(data);
};