In a ASP.MVC (1.0) project i managed to get weather info from a RSS feed and to show it up. The problem i have is performance:
i have put a RenderAction() Method in the Site.Master file (which works perfectly) but i 'm worried about how it will behave if a user clicks on menu point 1, after some seconds on menu point 2, after some seconds on menu point 3, .... thus making the RSS feed requesting new info again and again and again!
Can this somehow be avoided? (to somehow load this info only once?)
Thanks in advance!
You could use the server cache:
public ActionResult Index()
{
// try getting the weather from the cache
object weather = HttpContext.Cache.Get("weather");
if (weather == null)
{
// weather not cached => fetch it from RSS
weather = Repository.FetchWeather();
// store in cache for the 5 next hours
HttpContext.Cache.Add(
"weather",
weather,
null,
DateTime.Now.AddHours(5),
Cache.NoSlidingExpiration,
CacheItemPriority.Normal,
null
);
}
return View(weather);
}
I think if I were writting this app I'd download the weather details and store them in a db or xml file locally and read from that.
Weather doesn't change that much that you need minute by minute updates unless you're the weather channel or something.
Alternatively you could write this as a thread and have it report back when it's done loading. VS 2010 makes this a piece of cake btw.
So to solve this might be to give your code the ability to cancel a request and to do that you can't run this as a single threaded application. You are going to need to have the ability to kick off a request on a thread and cancel that on another request.
Faced with that I'd host it locally and run a process every say hour to update the data from the RSS feed.
Related
I have an arduino nano 33 ble that sends data from sensors every second or so. Right now I also have an app, written with Flutter and flutter_reactive_ble that receives the data. The problem is that I need to continue receiving data in background, but I am too inexperienced with Dart/Flutter, so I have trouble to do it.
For now I am using am implementation found on
https://github.com/ubiqueIoT/flutter-reactive-ble-example
I am using the subScribeToCharacteristic method.
My understanding is that it checks for new data only when there is something on the screen (using StreamBuilder<List>).
Is there a way to perform some basic math operations on the data in background and to dump it all to an array? I read about isolates and some other interesting techniques, but I was wondering whether there is a simpler solution, because those look a bit too difficult. I saw that apparently if I don't close my app completely (iOS) there is a way for it to continue to receive data for some time like 15-30 minutes, which is enough for my purpose, but there was no code/examples/etc.
I tried to put Stream out of StreamBuilder and to receive data just in the main body of Widget build, but nothing worked, I stopped receiving any data.
Thanks in advance!
here is a good starting point for you just use this plugin
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart'
as bg;
// Initialize the plugin.
bg.BackgroundGeolocation.ready(bg.Config(
desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
distanceFilter: 10.0,
stopOnTerminate: false,
startOnBoot: true,
));
// Start tracking location in the background.
bg.BackgroundGeolocation.start();
// Subscribe to the BLE device's characteristic to receive data.
bg.BackgroundGeolocation.subscribeToCharacteristic(
'DEVICE_ID',
'CHARACTERISTIC_ID',
(bg.CharacteristicEvent event) {
// Do some basic math operations on the data.
double data = event.value;
double result = data * 2 + 3;
// Dump the data to an array.
List<double> dataArray = [result];
// Do something with the data (e.g., save it to a database, send it to a server, etc.).
},
);
I have a MVC web database application where the records are basically documents with items.
Documents are locked, not items and they locked by code when the user looks in any of 4 or 5 different screens for any given document.
there is a 10 minute time out on the record locks. The user does not do anything with the record for 10 minutes and another can take the record. There is code that detects the lock was lost and taken by someone else. It works fine and is technically sound.
The workflow of the application relies on the lock being released when the user leaves the screen or closes the browser, or if they press the refresh button.
These are work fine on windows and android but not on ipad.
I understand there is no
beforeunload
on ios but I though there was
unload
or
pageHide
neither of these work.
Here is my code.
var isOnIOS = navigator.userAgent.match(/iPad/i)||
navigator.userAgent.match(/iPhone/i); var eventName = isOnIOS ?
"pageHide" : "beforeunload";
window.addEventListener(eventName, function (event) {
ReleaseRecordLock(); } );
This code works on all mentioned platforms except that the events don't fire on IOS.
It looks to me that this is deliberate on Apple's part so I an not thinking it will change.
So now the question.
What can I do to ensure that these records get unlocked if a user changes screens or closes the browser. If they don't no users will be able to access the document for 10 minutes which will not be acceptable.
Thanks
Edit... I don't need pop ups or notification. I just need reliable unlocking
As mentioned above none of the events that are supposed to work actually fire. pageHide and unload do nothing.
I found mentions of how to get around this problem but no details so I though I would detail it here.
This solutions works with areas and standard sites.
My solution to get around part of this was to detect if the browser is running on IOS and if so to change the link in the menu.
<li>
#{
if(Request.UserAgent.Contains("iPad") || Request.UserAgent.Contains("iPhone"))
{
<a onclick="IOSReleaseLock('controller', 'action')" href="javascript:void(0);">LinkText</a>
}
else
{
#Html.ActionLink("link Text","action","controller",new { Area = "Tasks" },null);
}
}
</li>
Every single link in the application has to have a function called IOSReleaseLock() available or the solution will not work. Not all pages lock records, only those that actually change documents. Reports, and basic website functions such as change password, log out, and the sys admin stuff do not need record locks.
At this point I have 2 versions of IOSReleaseLock()
This is the version that is used on pages that do not required unlocking.
function IOSReleaseLock(_controller, _action)
{
var url = '/__controller__/__action__/';
url = url.replace('__controller__', _controller);
url = url.replace('__action__', _action);
window.location.href = url;
}
This is the version that is placed on pages that required unlocking.
function IOSReleaseLock(_controller, _action )
{
var url = '/__controller__/__action__/';
url = url.replace('__controller__', _controller);
url = url.replace('__action__', _action);
UnloadingRecordLockRelease();
window.location.href = url;
}
Every link has a wrapper so every single page must load a version of IOSReleaseLock(). This includes your /home/index or where ever your application starts. If you miss one then once you are on that page your menu system links will not work anymore.
Pages that require the UnloadingRecordLockRelease() function load that version and the pages that do not require unlocking load the first version.
On IOS every time you click a link, IOSReleaseLock() is called. This may seem to be obvious, but for clarity, the version of IOSReleaseLock() that executes is the version that is on the current page, not the version on the page you are going to.
So as long as the user stays on the site and does not close the browser then the records are unlocked correctly.
When the user logs out all records are unlocked but I have no solution for when the browser tab is closed or when the browser is closed without the user logging out.
I have a reminder functionality using signal R in asp.net mvc
I have userinterface to set the reminder time, If the current time matches the reminder time , it invokes a popup.
I successfully implemented this functionality with Signal R by checking the database once in every 30 seconds by using javascript timer. If current time does not match, it gives '0'.If it matches, it return '1' and the popup is shown across all browsers. But can this checking the db for every 30 seconds can be replaced by signal R ? is there any way to bring this whole thing to signal R?
You can use System.Threading.Timer to create a periodical method call to both client and server side. According to Sample project created for stocks
_timer = new Timer(UpdateStockPrices, null, _updateInterval, _updateInterval);
It creates and Event-Delegate and calls UpdateStockPrices event timely with period of __updateInterval.
In This event(code given below) you can broadcast the remainder message from server to all clients or clients who are associated with that remainder.
You can write code as :-
Clients.All.updateStockPrice(stock);
You can refer to Timer from link:-
http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx
Yes, you can use Timer in the appdomain scope, application scope or at the hub level. Just get the sample from nuget, called "Microsoft.AspNet.SignalR.Sample". It implements stock timer that periodically broadcasts changes to all clients.
I have an iPhone app which is pulling just about all it's data from ASP.NET MVC services.
Basically just returning JSON.
When I run the app in the simulator, the data is pulled down very fast etc.. however when I use the actual device (3G or WiFi) it's extremely slow. To the point that the app crashes for taking too long.
a) Should I not be calling a service from the FinishedLaunching method in AppDelegate?
b) Am I calling the service incorrectly?
The method I'm using goes something like this:
public static JsonValue GetJsonFromURL(string url) {
var request = (HttpWebRequest)WebRequest.Create (url);
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using(var response = (HttpWebResponse)request.GetResponse()) {
using(var streamReader = new StreamReader(response.GetResponseStream())) {
return JsonValue.Load(streamReader);
}
}
}
Is there a better or quicker way I should be querying a service? I've read about doing things on different threads or performing async calls to not lock the UI, but I'm not sure what the best approach or how that code would work.
a) Should I not be calling a service from the FinishedLaunching method in AppDelegate?
You get limited time to get your application up and running, i.e. returning from FinishedLaunching or the iOS watchdog will kill your application. That's about 17 seconds total (but could vary between devices/iOS versions).
Anything that takes some time is better done in another thread, launched from FinishedLaunching. It's even more important if you use networking services as you cannot be sure how much time (or even if) you'll get an answer.
b) Am I calling the service incorrectly?
That looks fine. However remember that the simulator has a faster access to the network (likely), much more RAM and CPU power. Large data set can take a lot of memory / CPU time to decode.
Running from another thread will, at least, cover the extra time required. It can be as simple as adding the code (below) inside your FinishedLaunching.
ThreadPool.QueueUserWorkItem (delegate {
window.BeginInvokeOnMainThread (delegate {
// run your code
});
});
You can have a look at how Touch.Unit does it by looking at its TouchRunner.cs source file.
note: you might want to test not using (asking) for compressed data since the time/memory to decompress it might not be helpful on devices (compared to the simulator). Actual testing needed to confirm ;)
FATAL ERROR: CALL_AND_RETRY_2 Allocation Failed - process out of memory
I'm seeing this error and not quite sure where it's coming from. The project I'm working on has this basic workflow:
Receive XML post from another source
Parse the XML using xml2js
Extract the required information from the newly created JSON object and create a new object.
Send that object to connected clients (using socket.io)
Node Modules in use are:
xml2js
socket.io
choreographer
mysql
When I receive an XML packet the first thing I do is write it to a log.txt file in the event that something needs to be reviewed later. I first fs.readFile to get the current contents, then write the new contents + the old. The log.txt file was probably around 2400KB around last crash, but upon restarting the server it's working fine again so I don't believe this to be the issue.
I don't see a packet in the log right before the crash happened, so I'm not sure what's causing the crash... No new clients connected, no messages were being sent... nothing was being parsed.
Edit
Seeing as node is running constantly should I be using delete <object> after every object I'm using serves its purpose, such as var now = new Date() which I use to compare to things that happen in the past. Or, result object from step 3 after I've passed it to the callback?
Edit 2
I am keeping a master object in the event that a new client connects, they need to see past messages, objects are deleted though, they don't stay for the life of the server, just until their completed on client side. Currently, I'm doing something like this
function parsingFunction(callback) {
//Construct Object
callback(theConstructedObject);
}
parsingFunction(function (data) {
masterObject[someIdentifier] = data;
});
Edit 3
As another step for troubleshooting I dumped the process.memoryUsage().heapUsed right before the parser starts at the parser.on('end', function() {..}); and parsed several xml packets. The highest heap used was around 10-12 MB throughout the test, although during normal conditions the program rests at about 4-5 MB. I don't think this is particularly a deal breaker, but may help in finding the issue.
Perhaps you are accidentally closing on objects recursively. A crazy example:
function f() {
var shouldBeDeleted = function(x) { return x }
return function g() { return shouldBeDeleted(shouldBeDeleted) }
}
To find what is happening fire up node-inspector and set a break point just before the suspected out of memory error. Then click on "Closure" (below Scope Variables near the right border). Perhaps if you click around something will click and you realize what happens.