I'm currently building a Windows Service which creates a thread which runs every 30 minutes and updates a few fields on some entities which meet a criteria (and in the future, I want to add further threads to do other things, eg run one every 24 hours, one every week, etc). The service will get and update it's data using services which are already used by a web application and are injected using Ninject (along with the DbContext) - this all works fine using the InRequestScope() binding.
However, I've been thinking about how best to approach this using a Windows Service. Essentially, once the service starts and the thread is created, it runs continuously (aside from sleeping every 30 minutes) - and only ever stops if the Windows Service stops or the process gets terminated. My initial thought was to inject my DbContext and services using the InThreadScope() option of Ninject - so I'd have a DbContext for each thread. But is it generally good practice to have a DbContext that has such a long lifetime? This DbContext could be sitting there for weeks without being disposed - and I have a sneaking suspicion that this isn't such a a good idea (memory leaks, etc).
But if not, what is the best way to handle this scenario. I could create a new DbContext each time the thread runs, but how would I set up the Ninject bindings? Currently they're defined as:
Bind<IDbContext>().To<EnterpriseDbContext>().InThreadScope();
Bind<IUserRepository>().To<UserRepository>().InThreadScope();
// Etc
So I'm not entirely sure how I would structure this to create a new one within the thread. I looked at InTransientScope(), but this is causing my services to use different versions of the context, so my changes never get saved.
This seems like it would be such a common scenario - so would be great to hear anyone else's view.
Instead of creating threads that sleep until the next run you can use Quartz.Net as scheduling mechanism. In combination with InCallScope from the NamedScope extension you have the same behavior as InRequestScope of a WebService. Additionally you get a superior scheduling than just spawning threads that run in intervals. You can specify when they shall run using Cron Job syntax.
See:
ASP.Net MVC 3, Ninject and Quartz.Net - How to?
Quartz.NET, NH ISession & Ninject Scope
I particularly like #Remo's suggestions, and will be trying these on the next project I work on. However, I eventually solved the problem by using a custom InScope implementation - but setting a custom object that there should be scope to each time the thread ran. This way the context was recreated every time it ran (as disposed once the scope object was disposed).
Related
What is the difference between JavaFX 8 Task and Service and in which case is it better to use one over the other? What is better to use in database operations?
Main Difference between Task and Service - One Time versus Repeated Execution
A Task is a one off thing - you can only use a Task once. If you want to perform the same Task again, you need to construct a new Task instance.
A Service has a reusable interface so that you can start and restart a single service instance multiple times. Behind the scenes, it just takes a Task definition as input and creates new tasks as needed.
Example Use Cases
Task Example => monitoring and reporting progress of a long running startup task on application initialization, like this Splash Page example.
Service Example => The internal load worker implementation for WebEngine where the same task, loading a page asynchronously, needs to be repeated for each page loaded.
Recommendation - Initially try to solve your problem using only a Task and not a Service
Until you are more familiar with concurrency in JavaFX, I'd advise sticking to just using a Task rather than a Service. Tasks have a slightly simpler interface. You can accomplish most of what a Service does simply by creating new Task instances when you need them. If, after understanding Task, you find yourself wanting a predefined API for starting or restarting Tasks, then start using Service at that time.
Database Access Sample using Tasks
Either Task or Service will work for performing database operations off of the JavaFX application thread. Which to use depends on your personal coding preference as well as the particular database operation being performed.
Here is an example which uses a Task to access a database via JDBC. The example was created for JavaFX - Background Thread for SQL Query.
Background Information
The JavaFX concurrency tutorial provides a good overview of Task and Service.
There is excellent documentation in the Task and Service javadoc, including sample code for example use cases.
Worker, Task and Service definitions (from Javadoc)
Task and Service are both Workers, so they have this in common:
A Worker is an object which performs some work in one or more background threads, and whose state is observable and available to JavaFX applications and is usable from the main JavaFX Application thread.
Task definition:
A fully observable implementation of a FutureTask. Tasks expose additional state and observable properties useful for programming asynchronous tasks in JavaFX . . Because Service is designed to execute a Task, any Tasks
defined by the application or library code can easily be used with a
Service.
Service definition:
A Service is a non-visual component encapsulating the information
required to perform some work on one or more background threads. As
part of the JavaFX UI library, the Service knows about the JavaFX
Application thread and is designed to relieve the application
developer from the burden of managing multithreaded code that interacts
with the user interface. As such, all of the methods and state on the
Service are intended to be invoked exclusively from the JavaFX
Application thread.
Service implements Worker. As such, you can observe the state of the
background operation and optionally cancel it. Service is a reusable
Worker, meaning that it can be reset and restarted. Due to this, a
Service can be constructed declaratively and restarted on demand.
So I have some Java code that takes some time to complete (about 2 minutes). Nothing I can do about that.
But I am wondering how best to approach this in the XPages UI so that the user may still have to wait but has more control/interaction while it is running (not just a spinning wheel).
So from what I can see I can do the following.
Java class called in XPage wrapped in a thread.
Java Agent called from XPage in a thread.
Java Agent called from an XPage, but waits for a document to be updated.
Eclipse plugin (For in the client) is activated. Not sure how it would talk back to XPage though (via document?).
Any other methods?
If you created the thread in the XPage, is that going to cause any problems at the server end? Will I have to avoid using Notes objects in the Java class?
I would suggest using the OSGi Tasklet service, a.k.a. DOTS. This approach allows Java tasks to be scheduled or bound to events, just like agents, but perform significantly more efficiently than agents. Perhaps most pertinent to your need is the additional ability to trigger DOTS tasks via the console, which would allow your XPages code to start the Java code merely by issuing a remote console command via the session object.
In addition, check out the technique used in the XSP Starter Kit to provide a serverScope variable. If your code is running in a DOTS task (or even an agent), it's running in a different Java application, so it can't talk directly to the standard scope variables. The serverScope approach would theoretically allow you to store objects that can be accessed from both the XPage and the triggered task. This could aid in using Mark's technique, as mentioned above by Per, to convey progress to the user while the task is running: you'd just be storing the progress information in serverScope instead of sessionScope.
A solution would be to have an agent react on saving new documents in the database instead of kicking of the agent in your application and use threads ( because threads can be very dangerous and could easily kill your http task )
Another thing you could look into is why the code that you want to execute is taking 2 minutes to complete. What is the code for? Doing things in other databases or connect to other non notes resources?
What I want to do is to create a timer which is enabled on the Event Receiver FeatureActivated. I want to use this timer to execute once a day to check some items in a list and update the status for the items.
I can create and enable the timer - no problem. But when I try to access the SPSite object to get the list items I get the following error:
The sharepoint subset OM has been disabled for the current thread.
The timer is running in it's separate thread which causes the problem.
My question is: how do I access the SPSite object to get access to the list items from a separate thread?
Note: I'm using a timer because I can't use Timer Jobs in a Sandbox solution. Thank you.
I am afraid that your approach to run a task in the background is not possible. I can confirm that you cannot access the SP OM in an asynchronous delegate or run on a separated thread. I guess it is because the resource usage in sandboxed solutions is monitored and throttled. For example, you are not allowed to leave objects without disposing them too.
Not only you are disallowed to create an SPSite object with either string or Guid; you cannot pass the (SPSite)properties.Feature.Parent object that is available in the event receiver to the delegate too. (All properties of the object will throw the same exception.)
Generally I think that your solution would be too fragile. In a traditional solution, your code would be running in the w3wp.exe process and the first application pool recycle after activating your feature would kill the timer (with the entire application domain). Similarly, in a sandboxed solution you would be at the mercy of SPUCWorkerProcess.exe. You need some service host that will execute your code every day reliably.
Sandboxed solutions and/or SharePoint Online do not offer functionality for background-running services. You would have to run your code somewhere else, for example:
If you are allowed to deploy at least a small farm solution you can deploy the list item updating code as a SP timer job.
If you can afford running a Windows machine all the time you can write the list item refreshing code using the SP Client OM and install either as a Windows Service (timer loop) or as a Windows Scheduled Task (timed start). (The latter is simpler.)
If your solution is supposed to run in SharePoint Online and you cannot rely on a local Windows machine you can deploy it as a hosted service (Worker Role) in Microsoft Azure.
You can implement the regular updating functionality to run on demand in the sandboxed solution - as an ASPX page, for example. Then you would trigger the URL of the resource executing the code by public services like pingler or webcron.
Actually, the options 1 - 3 can be written the same way as the option 4 - the code to execute regularly within the sandboxed solution and the triggering code (very short and SP-independent) separately according to the scheduler's nature - it can be even a perl script using LWP scheduled by cron.
--- Ferda
The question is pretty much in the title, but I will elaborate.
I have a Silverlight application that acts as a slightly extended user interface.
The main part of my program will run on a server to keep the shared database coherent.
This is where my question comes in: Will two clients calling a WCF service each get a thread inside that service OR will they get a full AppDomain each?
The difference is that if the first is the case they can share the DB easily, but in the second scenario they cannot - as I understand it.
EDIT: This is because the DB makes use of the Identity Map pattern [Fowler] where objects used are saved in physical memory (static singleton variable) - multiple AppDomains would mess that up.
(I asked my university teacher and searched quite a bit before asking this, seemingly, simple question)
The threading model for WCF services is determined by the ConcurrencyMode you configure for your service: http://msdn.microsoft.com/en-us/library/system.servicemodel.concurrencymode.aspx.
Regarding AppDomains - that depends entirely on how you're hosting your service. If you're running a ServiceHost of your own, manually, there will always be exactly 1 AppDomain on the server side, unless you decide to start managing and spinning up your own.
If you're hosting inside IIS...it's up to IIS how it handles requests. It may reuse 1 AppDomain, it may spin up multiple AppDomains (unless you override the setting in the web.config to permit only 1 AppDomain per worker process), or it may spin up multiple physical worker processes (which inherently implies multiple AppDomains) if you have web garden mode enabled.
All this said, I'm not sure exactly why this would affect your data access strategy. Multiple threads or AppDomains should have no problem sharing a DB.
We have an SP timer job that was running fine for quite a while. Recently the admins enlisted another server into the farm, and consequently SharePoint decided to start running this timer job on this other server. The problem is the server does not have all the dependencies installed (i.e., Oracle) on it and so the job is failing. I'm just looking for the path of least resistance here. My question is there a way to force a timer job to run on the server you want it to?
[Edit]
If I can do it through code that works for me. I just need to know what the API is to do this if one does exist.
I apologize if I'm pushing for the obvious; I just haven't seen anyone drill down on it yet.
Constraining a custom timer job (that is, your own timer job class that derives from SPJobDefinition) is done by controlling constructor parameters.
Timer jobs typically run on the server where they are submitted (as indicated by vinny) assuming no target server is specified during the creation of the timer job. The two overloaded constructors for the SPJobDefinition type, though, accept an SPServer and an SPJobLockType as the third and fourth parameters, respectively. Using these two parameters properly will allow you to dictate where your job runs.
By specifying your target server as the SPServer and an SPJobLockType of "Job," you can constrain the timer job instance you create to run on the server of your choice.
For documentation on what I've described, see MSDN: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spjobdefinition.spjobdefinition.aspx.
I don't know anything about the code you're running, but custom timer jobs are commonly setup during Feature activation. I got the sense that your codebase might not be your own (?); if so, you might want to look for the one or more types/classes that derive from SPFeatureReceiver. In the FeatureActivated method of such classes is where you might find the code that actually carries out the timer job instantiation.
Of course, you'll also want to look at the custom timer job class (or classes) themselves to see how they're being instantiated. Sometimes developers will build the instantiation of the class into the class itself (via Factory Method pattern, for example). Between the timer job class and SPFeatureReceiver implementations, though, you should be on the way towards finding what needs to change.
I hope that helps!
Servers in a farm need to be identical.
If you happen to use VMs for your web front ends, you can snap a server and provision copies so that you know they are all identical.
Timer jobs per definition run on all web front ends.
If you need scheduled logic to run on a specific server, you either need to specifically code this in the timer job, or to use a "standard" NT Service instead.
I think a side effect of setting SPJobLockType to 'Job' is that it'll execute on the server where the job is submitted.
You could implement a Web Service with the business logig and deploy that Web Service to one machine. Then your Timer Job could trigger your web service periodically.
The it sould be not that important wher your timer job is running. SharePoint decides itself where to run the timer job.