Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Hive.Server.Core/3.2/ClientCommunicator.cs @ 2074

Last change on this file since 2074 was 2022, checked in by msteinbi, 15 years ago

Reset of client state when job finshed corrected (#466)

File size: 23.5 KB
RevLine 
[1121]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
[741]23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
[751]26using HeuristicLab.Hive.Contracts.BusinessObjects;
[780]27using HeuristicLab.Hive.Contracts.Interfaces;
28using HeuristicLab.Hive.Contracts;
[823]29using HeuristicLab.Core;
[1377]30using HeuristicLab.Hive.Server.DataAccess;
[842]31using System.Resources;
32using System.Reflection;
[1001]33using HeuristicLab.Hive.JobBase;
[1141]34using HeuristicLab.Hive.Server.Core.InternalInterfaces;
[1154]35using System.Threading;
[1445]36using HeuristicLab.PluginInfrastructure;
[1468]37using HeuristicLab.DataAccess.Interfaces;
[1596]38using System.IO;
[741]39
40namespace HeuristicLab.Hive.Server.Core {
[780]41  /// <summary>
42  /// The ClientCommunicator manages the whole communication with the client
43  /// </summary>
44  public class ClientCommunicator: IClientCommunicator {
[1154]45    private static Dictionary<Guid, DateTime> lastHeartbeats =
[1099]46      new Dictionary<Guid,DateTime>();
[1752]47    private static Dictionary<Guid, int> newAssignedJobs =
48      new Dictionary<Guid, int>();
[1998]49    private static Dictionary<Guid, int> pendingJobs =
50      new Dictionary<Guid, int>();
[783]51
[1154]52    private static ReaderWriterLockSlim heartbeatLock =
[1158]53      new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
[1154]54
[1468]55    private ISessionFactory factory;
[1369]56    private ILifecycleManager lifecycleManager;
57    private IInternalJobManager jobManager;
58    private IScheduler scheduler;
[842]59
[1998]60    private static int PENDING_TIMEOUT = 100;
61
[1121]62    /// <summary>
63    /// Initialization of the Adapters to the database
64    /// Initialization of Eventhandler for the lifecycle management
65    /// Initialization of lastHearbeats Dictionary
66    /// </summary>
[783]67    public ClientCommunicator() {
[1468]68      factory = ServiceLocator.GetSessionFactory();
69     
[1088]70      lifecycleManager = ServiceLocator.GetLifecycleManager();
[1141]71      jobManager = ServiceLocator.GetJobManager() as
72        IInternalJobManager;
[1272]73      scheduler = ServiceLocator.GetScheduler();
[842]74
[1133]75      lifecycleManager.RegisterHeartbeat(
76        new EventHandler(lifecycleManager_OnServerHeartbeat));
[783]77    }
78
[1121]79    /// <summary>
80    /// Check if online clients send their hearbeats
81    /// if not -> set them offline and check if they where calculating a job
82    /// </summary>
83    /// <param name="sender"></param>
84    /// <param name="e"></param>
[1088]85    void lifecycleManager_OnServerHeartbeat(object sender, EventArgs e) {
[1468]86      ISession session = factory.GetSessionForCurrentThread();
[1490]87      ITransaction tx = null;
[1088]88
[1468]89      try {
90        IClientAdapter clientAdapter =
91          session.GetDataAdapter<ClientInfo, IClientAdapter>();
92        IJobAdapter jobAdapter =
93          session.GetDataAdapter<Job, IJobAdapter>();
[1154]94
[1490]95        tx = session.BeginTransaction();
96
[1468]97        List<ClientInfo> allClients = new List<ClientInfo>(clientAdapter.GetAll());
[1154]98
[1468]99        foreach (ClientInfo client in allClients) {
100          if (client.State != State.offline && client.State != State.nullState) {
101            heartbeatLock.EnterUpgradeableReadLock();
102
103            if (!lastHeartbeats.ContainsKey(client.Id)) {
[1118]104              client.State = State.offline;
105              clientAdapter.Update(client);
[1468]106              foreach (Job job in jobAdapter.GetActiveJobsOf(client)) {
107                jobManager.ResetJobsDependingOnResults(job);
108              }
109            } else {
110              DateTime lastHbOfClient = lastHeartbeats[client.Id];
[1154]111
[1468]112              TimeSpan dif = DateTime.Now.Subtract(lastHbOfClient);
113              // check if time between last hearbeat and now is greather than HEARTBEAT_MAX_DIF
114              if (dif.TotalSeconds > ApplicationConstants.HEARTBEAT_MAX_DIF) {
115                // if client calculated jobs, the job must be reset
[1478]116                foreach (Job job in jobAdapter.GetActiveJobsOf(client)) {
117                  jobManager.ResetJobsDependingOnResults(job);
[1752]118                  lock (newAssignedJobs) {
119                    if (newAssignedJobs.ContainsKey(job.Id))
120                      newAssignedJobs.Remove(job.Id);
121                  }
[1468]122                }
123
124                // client must be set offline
125                client.State = State.offline;
126                clientAdapter.Update(client);
127
128                heartbeatLock.EnterWriteLock();
129                lastHeartbeats.Remove(client.Id);
130                heartbeatLock.ExitWriteLock();
131              }
132            }
133
134            heartbeatLock.ExitUpgradeableReadLock();
135          } else {
136            heartbeatLock.EnterWriteLock();
137            if (lastHeartbeats.ContainsKey(client.Id))
[1449]138              lastHeartbeats.Remove(client.Id);
[1716]139            foreach (Job job in jobAdapter.GetActiveJobsOf(client)) {
140              jobManager.ResetJobsDependingOnResults(job);
141            }
[1468]142            heartbeatLock.ExitWriteLock();
[1096]143          }
144        }
[1998]145        CheckForPendingJobs(jobAdapter);
146
[1490]147        tx.Commit();
[1088]148      }
[1490]149      catch (Exception ex) {
150        if (tx != null)
151          tx.Rollback();
152        throw ex;
153      }
[1468]154      finally {
155        if (session != null)
156          session.EndSession();
157      }
[1088]158    }
159
[1998]160    private void CheckForPendingJobs(IJobAdapter jobAdapter) {
161      IList<Job> pendingJobsInDB = new List<Job>(jobAdapter.GetJobsByState(State.pending));
162
163      foreach (Job currJob in pendingJobsInDB) {
164        lock (pendingJobs) {
165          if (pendingJobs.ContainsKey(currJob.Id)) {
166            if (pendingJobs[currJob.Id] <= 0) {
167              currJob.State = State.offline;
168              jobAdapter.Update(currJob);
169            } else {
170              pendingJobs[currJob.Id]--;
171            }
172          }
173        }
174      }
175    }
176
[741]177    #region IClientCommunicator Members
178
[1121]179    /// <summary>
180    /// Login process for the client
181    /// A hearbeat entry is created as well (login is the first hearbeat)
182    /// </summary>
183    /// <param name="clientInfo"></param>
184    /// <returns></returns>
[791]185    public Response Login(ClientInfo clientInfo) {
[1468]186      ISession session = factory.GetSessionForCurrentThread();
[1490]187      ITransaction tx = null;
[741]188
[1468]189      try {
190        IClientAdapter clientAdapter =
191          session.GetDataAdapter<ClientInfo, IClientAdapter>();
[1096]192
[1490]193        tx = session.BeginTransaction();
194
[1468]195        Response response = new Response();
196
197        heartbeatLock.EnterWriteLock();
198        if (lastHeartbeats.ContainsKey(clientInfo.Id)) {
199          lastHeartbeats[clientInfo.Id] = DateTime.Now;
200        } else {
201          lastHeartbeats.Add(clientInfo.Id, DateTime.Now);
202        }
203        heartbeatLock.ExitWriteLock();
204
205        clientInfo.State = State.idle;
206        clientAdapter.Update(clientInfo);
207        response.Success = true;
208        response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_LOGIN_SUCCESS;
209
[1490]210        tx.Commit();
[1004]211        return response;
[842]212      }
[1490]213      catch (Exception ex) {
214        if (tx != null)
215          tx.Rollback();
216        throw ex;
217      }
[1468]218      finally {
219        if (session != null)
220          session.EndSession();
221      }
[741]222    }
223
[1121]224    /// <summary>
225    /// The client has to send regulary heartbeats
226    /// this hearbeats will be stored in the heartbeats dictionary
227    /// check if there is work for the client and send the client a response if he should pull a job
228    /// </summary>
229    /// <param name="hbData"></param>
230    /// <returns></returns>
[1365]231    public ResponseHB ProcessHeartBeat(HeartBeatData hbData) {
[1468]232      ISession session = factory.GetSessionForCurrentThread();
[1490]233      ITransaction tx = null;
[783]234
[1468]235      try {
236        IClientAdapter clientAdapter =
237          session.GetDataAdapter<ClientInfo, IClientAdapter>();
[1096]238
[1468]239        IJobAdapter jobAdapter =
240          session.GetDataAdapter<Job, IJobAdapter>();
[1088]241
[1490]242        tx = session.BeginTransaction();
243
[1468]244        ResponseHB response = new ResponseHB();
[1500]245        response.ActionRequest = new List<MessageContainer>();
[783]246
[1500]247        ClientInfo client = clientAdapter.GetById(hbData.ClientId);
248
[1468]249        // check if the client is logged in
[1500]250        if (client.State == State.offline || client.State == State.nullState) {
[1160]251          response.Success = false;
[1468]252          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_USER_NOT_LOGGED_IN;
253          response.ActionRequest.Add(new MessageContainer(MessageContainer.MessageType.NoMessage));
[1160]254          return response;
255        }
256
[1500]257        client.NrOfFreeCores = hbData.FreeCores;
258        client.FreeMemory = hbData.FreeMemory;
259
[1468]260        // save timestamp of this heartbeat
261        heartbeatLock.EnterWriteLock();
262        if (lastHeartbeats.ContainsKey(hbData.ClientId)) {
263          lastHeartbeats[hbData.ClientId] = DateTime.Now;
264        } else {
265          lastHeartbeats.Add(hbData.ClientId, DateTime.Now);
266        }
267        heartbeatLock.ExitWriteLock();
268
269        // check if client has a free core for a new job
270        // if true, ask scheduler for a new job for this client
271        if (hbData.FreeCores > 0 && scheduler.ExistsJobForClient(hbData))
272          response.ActionRequest.Add(new MessageContainer(MessageContainer.MessageType.FetchJob));
273        else
274          response.ActionRequest.Add(new MessageContainer(MessageContainer.MessageType.NoMessage));
275
[1577]276        response.Success = true;
277        response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_HEARTBEAT_RECEIVED;
278
[1500]279        processJobProcess(hbData, jobAdapter, clientAdapter, response);
280        clientAdapter.Update(client);
[1468]281
[1490]282        tx.Commit();
[1468]283        return response;
[1124]284      }
[1490]285      catch (Exception ex) {
286        if (tx != null)
287          tx.Rollback();
288        throw ex;
289      }
[1468]290      finally {
291        if (session != null)
292          session.EndSession();
293      }
[780]294    }
[1500]295
296    /// <summary>
297    /// Process the Job progress sent by a client
298    /// </summary>
299    /// <param name="hbData"></param>
300    /// <param name="jobAdapter"></param>
301    /// <param name="clientAdapter"></param>
302    /// <param name="response"></param>
303    private void processJobProcess(HeartBeatData hbData, IJobAdapter jobAdapter, IClientAdapter clientAdapter, ResponseHB response) {
[1928]304      if (hbData.JobProgress != null && hbData.JobProgress.Count > 0) {
[1500]305        List<Job> jobsOfClient = new List<Job>(jobAdapter.GetActiveJobsOf(clientAdapter.GetById(hbData.ClientId)));
306        if (jobsOfClient == null || jobsOfClient.Count == 0) {
307          response.Success = false;
308          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_JOB_IS_NOT_BEEING_CALCULATED;
309          return;
310        }
311
312        foreach (KeyValuePair<Guid, double> jobProgress in hbData.JobProgress) {
313          Job curJob = jobAdapter.GetById(jobProgress.Key);
314          if (curJob.Client == null || curJob.Client.Id != hbData.ClientId) {
315            response.Success = false;
316            response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_JOB_IS_NOT_BEEING_CALCULATED;
[1577]317          } else if (curJob.State == State.abort) {
318            // a request to abort the job has been set
[1500]319            response.ActionRequest.Add(new MessageContainer(MessageContainer.MessageType.AbortJob, curJob.Id));
[1770]320            curJob.State = State.finished;
[1500]321          } else {
322            // save job progress
323            curJob.Percentage = jobProgress.Value;
[1577]324
325            if (curJob.State == State.requestSnapshot) {
326              // a request for a snapshot has been set
327              response.ActionRequest.Add(new MessageContainer(MessageContainer.MessageType.RequestSnapshot, curJob.Id));
[1772]328              curJob.State = State.requestSnapshotSent;
[1577]329            }
[1500]330          }
[1831]331          jobAdapter.Update(curJob);
[1500]332        }
[1630]333        foreach (Job currJob in jobsOfClient) {
334          bool found = false;
335          foreach (Guid jobId in hbData.JobProgress.Keys) {
336            if (jobId == currJob.Id) {
337              found = true;
338              break;
339            }
340          }
341          if (!found) {
[1752]342            lock (newAssignedJobs) {
343              if (newAssignedJobs.ContainsKey(currJob.Id)) {
344                newAssignedJobs[currJob.Id]--;
345
346                if (newAssignedJobs[currJob.Id] <= 0) {
347                  currJob.State = State.offline;
348                  jobAdapter.Update(currJob);
349                  newAssignedJobs.Remove(currJob.Id);
350                }
351              } else {
352                currJob.State = State.offline;
353                jobAdapter.Update(currJob);
354              }
355            } // lock
356          } else {
357            lock (newAssignedJobs) {
358              if (newAssignedJobs.ContainsKey(currJob.Id))
359                newAssignedJobs.Remove(currJob.Id);
360            }
[1630]361          }
362        }
[1500]363      }
364    }
[1121]365   
366    /// <summary>
[1577]367    /// if the client was told to pull a job he calls this method
[1121]368    /// the server selects a job and sends it to the client
369    /// </summary>
370    /// <param name="clientId"></param>
371    /// <returns></returns>
[1365]372    public ResponseJob SendJob(Guid clientId) {
[783]373      ResponseJob response = new ResponseJob();
[1154]374
[1272]375      Job job2Calculate = scheduler.GetNextJobForClient(clientId);
376      if (job2Calculate != null) {
[1154]377        response.Job = job2Calculate;
378        response.Success = true;
379        response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_JOB_PULLED;
[1752]380        lock (newAssignedJobs) {
381          newAssignedJobs.Add(job2Calculate.Id, ApplicationConstants.JOB_TIME_TO_LIVE);
382        }
[1160]383      } else {
[1272]384        response.Success = false;
385        response.Job = null;
[1160]386        response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_NO_JOBS_LEFT;
[805]387      }
[941]388      return response;
[780]389    }
390
[1374]391    private ResponseResultReceived ProcessJobResult(Guid clientId,
[1449]392      Guid jobId,
[1374]393      byte[] result,
[1133]394      double percentage,
[1374]395      Exception exception,
[1103]396      bool finished) {
[1468]397      ISession session = factory.GetSessionForCurrentThread();
[1490]398      ITransaction tx = null;
[1374]399
[1468]400      try {
401        IClientAdapter clientAdapter =
402          session.GetDataAdapter<ClientInfo, IClientAdapter>();
403        IJobAdapter jobAdapter =
404          session.GetDataAdapter<Job, IJobAdapter>();
405        IJobResultsAdapter jobResultAdapter =
406          session.GetDataAdapter<JobResult, IJobResultsAdapter>();
[1103]407
[1490]408        tx = session.BeginTransaction();
409
[1468]410        ResponseResultReceived response = new ResponseResultReceived();
411        ClientInfo client =
412          clientAdapter.GetById(clientId);
[1133]413
[1468]414        Job job =
415          jobAdapter.GetById(jobId);
[1811]416       
[1577]417        if (job == null) {
418          response.Success = false;
419          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_NO_JOB_WITH_THIS_ID;
420          response.JobId = jobId;
421          return response;
422        }
[1811]423        if (job.State == State.abort) {
424          response.Success = false;
425          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_JOB_WAS_ABORTED;
426        }
[1468]427        if (job.Client == null) {
428          response.Success = false;
429          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_JOB_IS_NOT_BEEING_CALCULATED;
[1577]430          response.JobId = jobId;
[1468]431          return response;
432        }
433        if (job.Client.Id != clientId) {
434          response.Success = false;
435          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_WRONG_CLIENT_FOR_JOB;
[1577]436          response.JobId = jobId;
[1468]437          return response;
438        }
439        if (job.State == State.finished) {
440          response.Success = true;
441          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_JOBRESULT_RECEIVED;
[1577]442          response.JobId = jobId;
[1468]443          return response;
444        }
[1772]445        if (job.State == State.requestSnapshotSent) {
446          job.State = State.calculating;
447        }
[1998]448        if (job.State != State.calculating && job.State != State.pending) {
[1468]449          response.Success = false;
450          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_WRONG_JOB_STATE;
[1577]451          response.JobId = jobId;
[1468]452          return response;
453        }
454        job.SerializedJob = result;
455        job.Percentage = percentage;
[1004]456
[1468]457        if (finished) {
458          job.State = State.finished;
459          jobAdapter.Update(job);
460        }
[1811]461        List<JobResult> jobResults = new List<JobResult>(jobResultAdapter.GetResultsOf(job));
462        foreach (JobResult currentResult in jobResults)
463          jobResultAdapter.Delete(currentResult);
[1103]464
[1468]465        JobResult jobResult =
466          new JobResult();
[1939]467        jobResult.ClientId = client.Id;
468        jobResult.JobId = job.Id;
[1468]469        jobResult.Result = result;
470        jobResult.Percentage = percentage;
471        jobResult.Exception = exception;
472        jobResult.DateFinished = DateTime.Now;
[1103]473
[1468]474        jobResultAdapter.Update(jobResult);
475        jobAdapter.Update(job);
[783]476
[1468]477        response.Success = true;
478        response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_JOBRESULT_RECEIVED;
479        response.JobId = jobId;
480        response.finished = finished;
481
[1490]482        tx.Commit();
[1468]483        return response;
484      }
[1490]485      catch (Exception ex) {
486        if (tx != null)
487          tx.Rollback();
488        throw ex;
489      }
[1468]490      finally {
491        if (session != null)
492          session.EndSession();
493      }
[780]494    }
[1096]495
[1374]496
[1121]497    /// <summary>
[1374]498    /// the client can send job results during calculating
499    /// and will send a final job result when he finished calculating
500    /// these job results will be stored in the database
501    /// </summary>
502    /// <param name="clientId"></param>
503    /// <param name="jobId"></param>
504    /// <param name="result"></param>
505    /// <param name="exception"></param>
506    /// <param name="finished"></param>
507    /// <returns></returns>
508    public ResponseResultReceived StoreFinishedJobResult(Guid clientId,
[1449]509      Guid jobId,
[1374]510      byte[] result,
511      double percentage,
512      Exception exception) {
513
514      return ProcessJobResult(clientId, jobId, result, percentage, exception, true);
515    }
516
517
[1449]518    public ResponseResultReceived ProcessSnapshot(Guid clientId, Guid jobId, byte[] result, double percentage, Exception exception) {
[1374]519      return ProcessJobResult(clientId, jobId, result, percentage, exception, false);
520    }
521
522    /// <summary>
[1121]523    /// when a client logs out the state will be set
524    /// and the entry in the last hearbeats dictionary will be removed
525    /// </summary>
526    /// <param name="clientId"></param>
[1154]527    /// <returns></returns>                       
[780]528    public Response Logout(Guid clientId) {
[1468]529      ISession session = factory.GetSessionForCurrentThread();
[1490]530      ITransaction tx = null;
[1096]531
[1468]532      try {
533        IClientAdapter clientAdapter =
534          session.GetDataAdapter<ClientInfo, IClientAdapter>();
535        IJobAdapter jobAdapter =
536          session.GetDataAdapter<Job, IJobAdapter>();
[1096]537
[1490]538        tx = session.BeginTransaction();
539
[1468]540        Response response = new Response();
541
542        heartbeatLock.EnterWriteLock();
543        if (lastHeartbeats.ContainsKey(clientId))
544          lastHeartbeats.Remove(clientId);
545        heartbeatLock.ExitWriteLock();
546
547        ClientInfo client = clientAdapter.GetById(clientId);
548        if (client == null) {
549          response.Success = false;
550          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_LOGOUT_CLIENT_NOT_REGISTERED;
551          return response;
552        }
553        if (client.State == State.calculating) {
554          // check wich job the client was calculating and reset it
[1928]555          ICollection<Job> jobsOfClient = jobAdapter.GetJobsOf(client);
556          foreach (Job job in jobsOfClient) {
557            if (job.State != State.finished)
558              jobManager.ResetJobsDependingOnResults(job);
[1127]559          }
560        }
561
[1468]562        client.State = State.offline;
563        clientAdapter.Update(client);
[902]564
[1468]565        response.Success = true;
566        response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_LOGOUT_SUCCESS;
567
[1490]568        tx.Commit();
[1468]569        return response;
570      }
[1490]571      catch (Exception ex) {
572        if (tx != null)
573          tx.Rollback();
574        throw ex;
575      }
[1468]576      finally {
577        if (session != null)
578          session.EndSession();
579      }
[780]580    }
581
[1369]582    /// <summary>
583    /// If a client goes offline and restores a job he was calculating
584    /// he can ask the client if he still needs the job result
585    /// </summary>
586    /// <param name="jobId"></param>
587    /// <returns></returns>
[1449]588    public Response IsJobStillNeeded(Guid jobId) {
[1468]589      ISession session = factory.GetSessionForCurrentThread();
[1490]590      ITransaction tx = null;
[1468]591
592      try {
593        IJobAdapter jobAdapter =
594          session.GetDataAdapter<Job, IJobAdapter>();
[1490]595        tx = session.BeginTransaction();
[1468]596
597        Response response = new Response();
598        Job job = jobAdapter.GetById(jobId);
599        if (job == null) {
600          response.Success = false;
601          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_JOB_DOESNT_EXIST;
602          return response;
603        }
604        if (job.State == State.finished) {
605          response.Success = true;
606          response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_JOB_ALLREADY_FINISHED;
607          return response;
608        }
[1998]609        job.State = State.pending;
610        lock (pendingJobs) {
611          pendingJobs.Add(job.Id, PENDING_TIMEOUT);
612        }
[1468]613
[1998]614        jobAdapter.Update(job);
615
[1369]616        response.Success = true;
[1468]617        response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_SEND_JOBRESULT;
[1490]618        tx.Commit();
[1369]619        return response;
620      }
[1490]621      catch (Exception ex) {
622        if (tx != null)
623          tx.Rollback();
624        throw ex;
625      }
[1468]626      finally {
627        if (session != null)
628          session.EndSession();
629      }
[1369]630    }
631
[1593]632    public ResponsePlugin SendPlugins(List<HivePluginInfo> pluginList) {
[1596]633      ResponsePlugin response = new ResponsePlugin();
[1637]634      PluginManager.Manager.Initialize();
[1596]635      ICollection<PluginInfo> allActivePlugins = PluginManager.Manager.ActivePlugins;
[1478]636
[1596]637      foreach (HivePluginInfo pluginInfo in pluginList) {
[1637]638        // TODO: BuildDate deleted, not needed???
639        // TODO: Split version to major, minor and revision number
[1596]640        foreach (PluginInfo currPlugin in allActivePlugins) {
641          if (currPlugin.Name == pluginInfo.Name
[1637]642              && currPlugin.Version.ToString() == pluginInfo.Version) {
[1478]643
[1596]644            CachedHivePluginInfo currCachedPlugin = new CachedHivePluginInfo {
645                Name = currPlugin.Name,
646                Version = currPlugin.Version.ToString(),
647                BuildDate = currPlugin.BuildDate };
648
649            foreach (String assemblyPath in currPlugin.Assemblies) {
650              currCachedPlugin.PluginFiles.Add(File.ReadAllBytes(assemblyPath));
651            }
652            response.Plugins.Add(currCachedPlugin);
653          }
654        }
655      }
656      response.Success = true;
657      response.StatusMessage = ApplicationConstants.RESPONSE_COMMUNICATOR_PLUGINS_SENT;
658
659      return response;
660
[1369]661    }
662
[741]663    #endregion
664  }
665}
Note: See TracBrowser for help on using the repository browser.