Starting Windows service automatically at Windows startup that is dependent on Oracle - c#

I have developed a Windows Service, that must start automatically during Windows startup. This service connects to an Oracle db, so I made my service dependent on Oracle Services by sc command line utility:
sc config MyService depend= OracleServiceXE/OracleXETNSListener
So far so good, dependency was set succesfully. But when Windows starting, my service could not start, I get the following (Oracle) error message: "ORA-12528: TNS:listener: all appropriate instances are blocking new connections".
As I think, the Oracle services are started when my service starts, but they are not 'fully initialized'. After some seconds I can start my service from service consol without any problem.
So, how can I start automatically my service at Windows Startup which is dependent on an Oracle DB connection?
My service was developed in C# on .Net 4 platform, in VS 2010 environment.
Pls. help me, it is a really important task form me!

Remember, the code for your service's startup should do as little as possible. In other words, don't have your service startup check for availability of the Oracle server, or indeed do anything. Have your service do the following:
Log the fact that it's started
Load any applicable configuration from config files/registry/etc
Spin-up a thread that will try and "startup" the service properly every N seconds, and will repeat M times until it gives up. Have N and M configurable from your config file/registry
Have the thread "try" to connect to the applicable Oracle server and if it fails, go to sleep for N seconds, and do this M times. If it succeeds it can then start doing the "meat" of what it's supposed to.
Ironically, it's probably the fact that the Oracle service does something similar to what I've proposed you do that's causing you the problem. By returning "Yes, I've started" quickly back to Windows when it's started, it allows your service to then be loaded, even though Oracle is still busy spinning stuff up. Ideally in this scenario rather than rejecting your requests, Oracle should enqueue them for processing when it is ready.

Related

How to keep Windows Service running after computer is restarted?

I have this Windows Service (using SqlDependency) that sends me an e-mail everytime it is started and everytime a new row is inserted on my Sales table (the database has Service Broker enabled).
I also write a log file to register when the service is started, the data is inserted to the table, if the e-mail was successfully sent and when the service is stoped.
When I started the service manually, it worked just fine.
Then I turned my PC off and on again and inserted data on my table
in the database, but nothing happened (no e-mail sent and no
register in my log file).
I restarted the service manually and it worked fine again.
Turned the PC off and on again and nothing heppened again.
I made some research and changed the initialization type to Automatic
and tried again. And nothing happened again.
I changed the initialization type to Automatic Delayed and tried
again. But it didn't work too, even 1 hour after I turned the PC on.
Now I manually restarted the service and the log file registered that
the service stoped and started, I received the email that the service
started and, after I inserted data in my database table, both log
register and email message worked just fine.
Everytime it didn't work, I checked the services manager in Windows and it was marked as "Running".
I don't know if I need to configure something different in my code or in my service properties.
Has anybody ever had this issue?
EDIT
I modified my service and included a timer, so every minute passed it writes the time in my log text file. After I restarted my PC, the log file continued to register the time every minute, but did not register the insert I made in my database table.
My guess is that the service might be losing the database connection when the PC is restarted, so the SqlDependency cannot detect the changes. Does it make any sense?
Your service depends on SQL Server, but your service is probably starting before SQL Server has been started, or finished starting. This may be causing your SqlDependency to fail.
You can mark your service as being dependent on SQL Server, which means:
Windows won't attempt to start your service until SQL Server has started and is ready, and
Starting your service will cause Windows to start SQL Server before it starts your service
This can be achieved on the command-line with the sc command (which will need to be run at an administrative command prompt). If your SQL Server instance is named MSSQLSERVER and your service is named MyService the command would look like this:
sc config MyService depend= MSSQLSERVER
Note: The space after = and before MSSQLSERVER matters. The detailed syntax can be found on learn.microsoft.com.
Once this command has run successfully, this is what you'll see when looking at the properties of your service in Control Panel > Administrative Tools > Services:

Is it possible for a WCF service to restart itself?

I'm currently working on a WCF service which holds and processes all the data for an application, while a MySql database is used for persistence. The service currently works as a singleton (InstanceContextMode.Single) and supports multiple concurrent calls (ConcurrencyMode.Multiple). I'm not really sure what version of IIS the service is hosted in, but I believe it is IIS 7.5.
The problem is that there are some situations where if an exception occurs (eg.: while releasing ReaderWriterLockSlim locks), the service will be in a unreliable state and data may get corrupted (and written into the database) if users keep calling the service.
Currently I know of two ways of preventing users from calling the service: either closing the InstanceContext object (through OperationContext.Current) or raising an exception in IDispatchMessageInspector.AfterReceiveRequest if the service is in a faulted state. The problem with both of these two ways is that they make the service unavailable until I restart the server/application pool (which I can't, see note below) or re-deploy the service.
Important note: Although I have Full-Trust, the service is currently hosted on a shared server, so I can't restart the server or the entire application pool (if that is possible) because that would restart other people's services as well.
Update:
I tried unloading the AppDomain as #usr suggested, but that doesn't work as well: after unloading it, an exception is raised for every call to the service.
Currently I'm trying to find out what WCF/IIS uses as a condition to decide if the service should be created again. I noticed that in the code generated for the client checks if there is any channel available to communicate with the service; if there isn't, a new one is created. Thus, I tried to close all channels in the service: I tried closing OperationContext.Current.InstanceContext.OutgoingChannels, OperationContext.Current.InstanceContext.IncomingChannels, OperationContext.Current.Channel, and many other properties with "Channel" in their name, all of them with no success.
The way to warm-up anything in IIS prior to version 7.5 is using scheduled console application to ping your web site / services and warm them up. It's not a good fix but it works, it is easy and I saw it on every project which had to deal with this requirement.
Or If you are using IIS 7.5 then
You can use Windows Server AppFabric, it has Auto Stat feature to keep the service always on. But you need to be on IIS 7.5 to install App Fabric.

Running console applications from a WCF service - where to host it?

Currently working on a .NET solution for an application server. I'm using .NET 4.0 running on Windows Server 2008 R2 with IIS 7.5.
My requirements are:
The application server can run multiple Console applications at once on a schedule - Quartz.net looks like a really good solution to this problem - and is working well for me so far
The application server will also host a web application that will report on jobs (what time they ran, what they did, how long they took etc)
I would like to be able to restart the "service" that is running my jobs and trigger ad hoc jobs from the web interface.
The Service that is running my jobs needs to run all the time
Once this is live I will not have direct access to the machine to restart a Windows Service, but i could potentially setup IIS to be able to do this for me.
WCF Services looks quite promising to me - but I'm not sure where to host it. My current project uses a WCF Service to run console applications using the Quartz.net plugin. Configuration for what to run and when to run it is stored in an oracle database and my WCF service connets directly to the database to retrieve this information (not sure if that is the intended use of WCF).
If I host the WCF Service in IIS / WAS then running the console applications might be a security concern from what I've read. I can keep the WCF service running all the time using appFabric at least. Alternatively I could host it in a Windows Service and allow my web app to consume the WCF service to report on the jobs. I'm concerned about using a Windows Service though as I wont have direct maintenance access to this machine and if it breaks I'm in trouble. I would really like to be able to do the maintenance from a web application. A windows service also feel a little unnecessary given it can be hosted from IIS.
So my question is - is a WCF Service the right approach to this problem or can anyone think of a better approach?
If a WCF service is a good approach - where should I host it so that I can perform maintenance via a web interface given I will not have direct access to the machine itself?
Should the WCF service be the one to start and schedule the jobs?
I think you're overengineering it, possibly.
The Problem: You have a web site which needs to start up jobs on an ad-hoc basis. Other jobs will be run to a fixed schedule. The web site will report on all/any of these jobs.
For running the scheduled jobs, a Windows Service using Quartz is indeed an ideal solution for the fixed schedule part. However, to report on those jobs the data must be collected by the Service and made available. A service can be set up to restart on fail, so you can guarantee that it will always be running (barring a minute or two when it's restarting if it fails - and why should it?. However, any history will be lost unless the Service stores it somewhere it can be retrieve it after a restart.
The simpler solution to the web site getting the history is for the Service to write its data to a database. Then it doesn't worry about a restart: all the history has already been saved, and the data can be read by the web site at any time.
Similarly, if the web site talks directly to the Service (as a WCF Service or otherwise) then what happens if the service is not currently running? The request gets fails until the restart is completed. Frustrating for the user. Alternatively, the web site puts the request into the database. The service monitors the database for requests, and starts jobs appropriately when it sees a new request. If a request is written while the service is not running, when it restarts it will see the request(s) in the DB and execute them.
So I think using a WCF service is overkill, and actually introduces some problems: persistence of history, and what to do about requests made while the service is down. These problems don't arise if you go the way I've described.
Cheers -

C# database connection delay

I have an app, it's done and working, but the users report a small problem with it, and quite frankly i susspected it could be a problem.
As the title says the app is written in c# (.net 3.5) and it's using SQL DB.
The "problem" is - when the app is first started, it takes about a half a minute to conenct to database.
Could this be somehow reduced?
Thank you for your time!
EDIT1:
the DB is local.. sql server and .net framework are installed at the same time as the app
EDIT2:
when the app is stared it all works fine, and when users open the winform where some DB work needs to be done, the first time it's started they have to wait about half a minute, after that it works fine..
From questions I asked in comments and their respective answers, the conclusion I offer is this:
It seems to me that the server agent service may be set with a startup mode of Manual. This means the service will only start as and when required by an application:
Manual starts a service as required or when called from an application (according to definition, but only some of the time in practice, depending on the service)
To mitigate this you could create a custom install action which would, as part of your product installation, set this startup mode to Automatic - this would cause the service to start when Windows starts.

How to Synchronize Windows Service Access to SQL Server Database on Startup?

I have a WCF service that is running as a windows service. As soon as the WCF service starts it will try to connect to the DB and do some initialization processing.
I'm having an issue when I restart my machine (the wcf service is set to start automatically), the service would get an exception as too sql is busy. So it seems like the sql is trying to start and at the same time my service is trying to communicate with it.
For now, I did something like try/catch and I sleep for like 10 sec in my catch and I retry again until my initialization is successful.
This works pretty well. But I'm looking for a more elegant solution.
I don't want to set a dependency on sql on my windows service as the service can be installed on a different machine that the DB.
You might try configuring the "Recovery" options of your service when you deploy it to have it restart itself when it fails to load. You can do this via the SC.EXE command-line tool, WMI, or manually through the service properties (services.msc MMC).
Trying [n] times, with some timespan between retries, before ultimately failing if still unable to connect is not a bad solution if you consider monitoring and alerting.
The service actually failing to start will write warning/error events to the Windows event log, potentially triggering monitoring and alerting behavior that you might not want if its just waiting on a dependency to be available, and it will eventually recover.
HTH,
Z

Categories

Resources