I'm a beginner iOS developer, and I'm trying to build a CRM system to learn the different aspects of developing.
I have a question regarding the preferred way to connect to an external SQL-server. I'm using Karl Krafts' Obj-C MySQL Connector by the way.
Right now I init the Database-controller (which in turn creates, then idles the connection to the server) object in my app delegate (didFinishLaunchingWithOptions), and that gives me some unwanted side-effects.. The screen is black a long time at startup if connection to the DB is slow, and sometimes the app is "too fast" and the query is trying to execute before the connection has been fully established - resulting in an exception being thrown.
The behavior I want (and guess is the preferred) is that the GUI loads up first, and then the initialization of the DB-controller and connection is established in a background thread - updating the GUI when the data has been acquired.
How would I achieve this? I have tried a number of different ways i've come across in my research, dispatch_queues and initing it straight from the viewDidLoad etc, but none give me the desired "GUI then data"-effect.
Also, would it be preferred to have an idling connection during the session of the program - or should each query 'connect - do its thing - disconnect'?
Regards, Christopher
Commandment One: don't do networking on the main thread - it's reserved for the UI. Else your app will have a laggy and frozen UI.
Commandment Two: instead of a lot of sequential synchronous calls, use asynchronous calls (GCD, background threads, etc.), events and callbacks. Cocoa (Touch) is designed with this in mind, so it's easy to do.
Commandment Three: if you launch something automatically, let it be launched when the app is fully ready. Let the call to the web service be the last one in application:didFinishLaunchingWithOptions:. Even better, let the user have the possibility to initiate the login via a user action, i. e. by pressing a "Login" button.
Commandment Four: read the first three Commandment again and keep them in mind. Practice them until you know them well.
Related
I'm trying to get FLTK running in my c++ project. I'm creating an OMNeT++ simulation and would like to use the GUI like an emulated host, that is, I can make a send button and the host attached to the GUI will queue up a message to send in the simulation.
The issue I'm having is that, when the FLTK window runs, it waits for a response which causes the whole simulation to freeze until I close the window. My solution was to run the GUI in a separate thread. However, now I'm getting this error:
Tcl_ServiceModeHook: Notifier not initialized
Below is the code for the class containing the thread and the GUI.
#include <Enumerations.H>
#include <Fl.H>
#include <Fl_Box.H>
#include <Fl_Widget.H>
#include <Fl_Window.H>
#include <GUI.h>
void GUI::callThread() {
t = std::thread(&GUI::openWindow, this);
}
int GUI::openWindow() {
Fl_Window *window = new Fl_Window(300,180);
Fl_Box *box = new Fl_Box(20,40,260,100,"Hello, World!");
box->box(FL_UP_BOX);
box->labelsize(36);
box->labelfont(FL_BOLD+FL_ITALIC);
box->labeltype(FL_SHADOW_LABEL);
window->end();
window->show();
return Fl::run();
}
All I do to call it is:
GUI *g = new GUI();
g->callThread();
If I instead just call openWindow() directly, The window opens fine but it waits for an action so the rest of the simulation is not able to continue.
I'm trying to make this cross-platform (Has to work on Mac and Windows). I tried Qt (too complicated to set up) and wxWidgets (make errors on my computer) so FLTK seemed like one of the next best choices.
If anyone knows how to fix this error or has any opinions on a better way to set up my GUI, I'm all ears. This just seemed like the only thing I could do.
OMNeT++ 5.0 and up has Qtenv, which is a QT based runtime (Tkenv is now deprecated), so the whole QT setup, dependency etc. is done for you by OMNeT++. Qtenv will be the default runtime in OMNeT++ 5.1
It's not really clear what you are trying to achieve. If you want to insert events into the event queue whenever you press a button, you definitely have to use a separate thread, but you have to clarify how the simulation and wall clock time is related to each other. If they must be synced, you need to implement a real-time scheduler that syncs the simulation time with the wall clock time. The sockets example in OMNeT++ does this and behaves similarly what you describe except that the external event inserted into event queue is coming from a socket (where you can attach with a browser) isntead of coming from a GUI.
If you don't care about synchronization i.e. you want to use this for some kind of demonstration, then you don't have to use a real-time scheduler, but you should be aware the OMNeT++ is inherently single threaded and your GUI is running in a separate thread, so you have to sync those too. i.e. It's absolutely forbidden to access ANYTHING that OMNET is using from the GUI thread (or bad things will happen).
And the poor man's solution: if you just want to trigger an event (i.e. you really need only a button). Write an application in the host which regularly polls a volatile bool parameter. If it finds the parameter "true" it sends the event and then sets the parameter to "false". Now how you trigger an event? You can browse the parameters of the given node in the property inspector (lower left panel in runtime) and you can change it's value by hand back to true, then allow the simulation to continue. On the next poll, the host's app will detect again that the parameter is true and do the sending again. Obviously it's limited, but it gives a limited interaction without writing too much code (and all the multithreading issues are handled by the runtime itself)
I am using perl tray from activestate and have a question. I am wanting to make some type of ui or way for a user to set "Settings" on my application. These settings can just be written / read from a text file that is stored on the users computer.
The part I am not understanding though is how to go about making a ui. The only thing i can think of is showing a local perl page that runs on their computer to write to the file. However, I'm not sure how i could get perl to run in the browser when only using perltray.
Any suggestions?
PerlTray is an odd duck. It has an implicit event loop that kicks in after you either fall off the end of your program or after your 1st call to exit(). This makes it incompatible with most other common GUI event loops or most mini-server techniques that operate in the same process & thread.
2 possibilities come to mind:
Most Likely you'll have success spawning a thread or process that creates a traditional perl GUI or a mini-server hosting your configuration web-app. I'd probably pick Tkx, but that's just my preference.
I have a suspicion that the Event Loop used by Win32::GUI may actually be compatible with the event loop in PerlTray, but some experimentation would be required to verify that. I generally avoid Win32::GUI because it's not platform independent, but if you're using PerlTray, you're tied to Windows anyway...
I am trying to plan out where to put my MySQL connection code -
MCPConnection *conn = [[MCPConnection alloc] initToHost:#"" withLogin:#"" usingPort:#""];
etc. from MCPKit on the mac. My aim is to make as few connection instances as possible through the whole app (if possible just one will be awesome).
The only 3 places i can think of putting it are -
The app delegate, but then how would I use the same connection in other classes (data encapsulation)
Place code in Each and every Window/View controller that requires it to fulfil each individual purpose (but this means a lot more code and a large number of connections which i do no want).
Or finally setting up an individual class for all the the MySQL queries and a singular connection. (but then how to do that so that the methods in this class are easily callable, or so that the SQL statements/queries can be adaptive enough for every other class that uses the methods).
i hope that hasn't been too confusing - the main point is this - where do i put the connection code, does it carry between classes well, or does it need to be called individually and successively throughout use of the app.
Thank you for your time.
As a simple solution, you can use Singleton pattern and replace init code with call to static getInstance. The only public method of singleton wrapper would be getConnection, which then you use as normal. Yep, you can pull common sql-building methods into that class, but that leads to code bloat, better use Flyweight pattern for separate-type queries.
The only drawback of such design is that access to that single shared database connection must always be serialized, which may render some your UI slow and irresponsive if there are multiple simultaneous threads accessing database.
I'm using Northscale 1.0.0 and need a little help getting it to limp along for long enough to upgrade to the new version. I'm using C# and ASP.NET to work with it using the Enyim libraries. I currently suspect that the application does not have enough connections per the socketPool setting in my app.config. I also noted that the previous developer's code simply treats ANY exception from an attempted Get call to MemCache as if the item isn't in the cache, which (I believe) may be resulting in periodic spikes in calls to the database when the pool gets starved. We've been having oddball load spikes that don't seem to have any relation to server load. I suspect that he is not correctly managing the lifecycle on the connections to Northscale and that we are periodically experiencing starvation in the socket pool as a result, but I'm unable to prove it.
Is there a specific exception I should be looking for when I call the Get method to retrieve items from cache? I'm not really seeing much in the docs that gives me sufficient information on this. Anybody have any sample code on this? I'd even accept java or php code, as I think the .NET libraries were probably based on one of those anyway.
Any ideas?
Thanks,
Will
If you have made the connection correctly to the membase server(formerly Northscale) typically you only get an exception on 'get' when it's not a hit.
We had a case when exceptions had gone in some kind of infinite loop.
Stack traces were very big and we log all of them.
That flood our Oracle database and when redo logs reached their size limit db stopped.
EDIT: Of course that the most important thing is to find the cause of infinite loop an correct the bug in the system. We already did that and that is not the question here.
The system could have more bugs like that (it's an windows service and it's running constantly) and in that case one app broke the whole DB, meaning all applications on that Oracle DB.
I'm mostly interested in your experiences, architecturally. And that from other logging frameworks like log4net, log4j and others. How do they handle flood of exceptions ? Just handle them like all other exceptions ?
I think your situation illustrates that there should definitely be some mechanism in place to prevent exception logs from causing a denial-of-service anywhere, as this has done.
If you use the Windows event logs, this can be handled for you automatically, as old records can automatically be wiped out when the log is full. You could code a DB-based system to do the same thing, as well.
Of course, you want to do everything you can to eliminate such errors in the first place where ever possible, too!
Another option may be to detect and ignore multiple, consecutive errors of the same time... perhaps simply updating a count property/field instead.
I'd worry more about the root cause of the infinite loop then I would about limiting logging.
I'd check your code for methods that catch an exception, log the stack trace, and re-throw. I'd argue that catching and re-throwing is not exception handling. If a class truly can't handle the exception, it's better to let it simply bubble up until it reaches a single point where someone can deal with it.
Redo logs? How often do you flush those? Surely you don't have one big transaction, do you?
Can you do the logging to a different database with no redo logs? That will protect the production database.
In our applications whe have a central exceptionhandler where all execeptions go through
void OnExceptionOccurs(Exception ex,
string enduserFriendlyContextDescription,
string tecnicalContextDescription,
ILogger loggerBelongingToProcess)
that handler can decide how to log and you have a central location for breakpoint when debugging