How to force specific service instance in Task Scheduler in NAV 2017?

Hello,

Before NAV 2017 we had Job Queue table and in the job queue table it was possible to specify that some tasks must be running on a specific NAV service.
This was quite helpful feature e.g. in the following situations:
  1. Background printing - it was sufficient to configure printers only on one machine and pass the printing jobs via that machine
  2. Different user accessing SQL - if different NAV services had different service users, it was immediately visible in the SQL statements which service owned which request.
  3. Different permissions - it was possible to give different services different system permissions via its Service Account.

With Task Scheduler it seems we are missing the option of forcing specific host and/or service to take care about the scheduled task.
Could anybody please suggest if there is any workaround in which we could force certain tasks to run on specific services?

I am aware only about the following which I do not particularly like:
  1. Fire from Scheduled Task that task on a specific service using Web Services. But then the impersonation would not work :neutral: ...
  2. Use Old Job Queue instead of Task Scheduler.

Any suggestions on how to force specific service instance using Task Scheduler?

Also if you have some in-depth technical explanations on how NAV 2017 task scheduler works with multiple services are welcome. At the moment I take it so that the service to process the scheduled task is chosen somehow behind the scenes. But how that somehow works is less clear to me ...

Thanks,
Igor

Answers

  • RoelofRoelof Posts: 338Member
    I have the same question as Igor.
    Any ideas anyone?
    Roelof de Jong
    http://www.esopro.com
  • HannesHolstHannesHolst Posts: 85Member
    edited 2017-03-29
    Hey there,

    As I understand the documentation, there is no "build in" option to handle this requirement.
    When Codeunit 448 is called, why not check the current sessionID with the sessionID of the desired ServiceTier?

    Thinking one step further, it is thinkable to create an additional dispatcher which calls a STARTSESSION with the desired SessionID.

    Cheers,
  • OldNavDogOldNavDog Posts: 87Member
    Task Scheduler does not Create "Sessions" in the usual Sense, i.e. in the Active Session Table (2000000110); only "Session Events" in the Session Event Table (2000000111).

    Now if someone would only tell me how you DEBUG a Task Scheduler Task...
    Experience is what you get, when you don't get what you want. --Anon.
  • igor.chladiligor.chladil Posts: 25Member
    Hi Hannes,

    just a quick response to your suggestions - when Job Queue Dispatcher runs it already runs on a specific service instance and I am not aware about any way which would migrate that session to another service instance. I am not also aware about any way which would spawn a new session on another service instance (STARTSESSION happens on the same service instance).

    Former Job Queue method actually spawned job queue entries looping session on all the service instances where it was allowed. And that is why it could filter out its own job queue entries and start these on correct service instance using STARTSESSION.

    I however like Task Scheduler and I am missing this only bit - possibility to give it the hint about the service it should execute on.

    OldNavDog - you can debug scheduled task by using breakpoint & starting Debug Next. Scheduled Task fires the background session for the time needed for its execution.

    Regards,
    Igor
  • HannesHolstHannesHolst Posts: 85Member
    Hi,

    Just stumbled across this topic in Google as I did a research for a similar topic :-)

    @igor.chladil
    You could use something like the following to achieve the requirement.
    I didn't test it, but it should be starting point.

    1) store in the Job Queue the Server and Instance which you want to run the code in
    2) in your Dispatcher-Codeunit (for example 448) make something like this:
    // get current server instance
    ServerInstance.GET(SERVICEINSTANCEID);
    IF ServerInstance."Service Name" <> JobQueueEntry."Server Instance to be executed on" THEN
      EXIT;
    
    // check for current session
    IF SESSIONID <> JobQueueEntry."Session to be executed in" THEN
      EXIT;
    
    ExecuteFunction(); // call Codeunit or Report as configured in Job Queue Entry here
    

    Additionally you could do something like this:
    // get current server instance
    ServerInstance.GET(SERVICEINSTANCEID);
    IF ServerInstance."Service Name" <> JobQueueEntry."Service to be executed on" THEN
      EXIT;
    
    // execute session directly
    STARTSESSION(JobQueueEntry."Session to be executed in",CODEUNIT::"whatever",COMPANYNAME,Rec);
    

    The Task Scheduler basically calls every time the same Codeunit (448 in standard config).
    Each of the NAS Services will go through the code and checks if the Server Name matches.
    If not, do nothing (make sure that the Execution DateTime of the Job Queue Entry will not be updated).
  • JuhlJuhl Posts: 435Member
    The workaround only solves job queue entries. Not Scheduled Task.
    Follow me on my blog juhl.blog
  • HannesHolstHannesHolst Posts: 85Member
    edited 2017-08-15
    @Juhl: Everytime you push "Set Status to Ready" for a Job Queue, a Scheduled Task will be created. If you have built your own solution, build a setup in NAV to identify the Scheduled Tasks and on which Server to run. Then implement the above code into the Codeunit your Scheduled Task executes.
Sign In or Register to comment.