Free cookie consent management tool by TermsFeed Policy Generator

source: branches/thasling/DistributedGA/DistributedGA.ContactServer/ContactServiceImpl.cs @ 13971

Last change on this file since 13971 was 13943, checked in by thasling, 8 years ago

#2615:
implemented lock for timers, because if elapsed-method takes longer than the timer to elapse again, the method is called by another thread conccurently

File size: 3.5 KB
Line 
1using System;
2using System.Collections.Concurrent;
3using System.Collections.Generic;
4using System.IO;
5using System.Linq;
6using System.ServiceModel;
7using System.Timers;
8using DistributedGA.Core.Domain;
9
10namespace DistributedGA.ContactServer {
11
12  [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
13  public class ContactServiceImpl : IContactService {
14
15    private ConcurrentDictionary<PeerInfo, DateTime> allPeers = null;
16
17    private Timer timer = null;
18
19    private Object logLock = new Object();
20
21    private Object timerLock = new Object();//if elapsed takes too long, another thread also enters the method
22
23    public ContactServiceImpl() {
24      allPeers = new ConcurrentDictionary<PeerInfo, DateTime>();
25
26      timer = new Timer(1000); //each hour
27      timer.Elapsed += CleanUpContactTable;
28      timer.Start();
29    }
30
31    public void RegisterPeer(PeerInfo source) {
32      try {
33        UpdateHeartbeat(source);
34      }
35      catch (Exception ex) {
36        AddError("ContactServiceImpl.RegisterPeer", ex);
37      }
38    }
39
40    public List<PeerInfo> GetPeerList(PeerInfo source) {
41      try {
42        UpdateHeartbeat(source);
43        //only return peers of the same work group and not the sender itself
44        return allPeers.Keys.Where(x => {
45          if (source.ProblemInstance.Equals(x.ProblemInstance) &&
46              (!(x.IpAddress.Equals(source.IpAddress) && (x.Port.Equals(source.Port)))))
47            return true;
48          else
49            return false;
50        }).ToList();
51      }
52      catch (Exception ex) {
53        AddError("ContactServiceImpl.GetPeerList", ex);
54        return null;
55      }
56    }
57
58    public void MakeLog(PeerInfo source, string msg) {
59      try {
60        // TODO
61        lock (logLock) {
62          File.AppendAllText("Log.txt", string.Concat(source.IpAddress, ":", source.Port, ",", source.ProblemInstance, ",", msg, Environment.NewLine));
63        }
64      }
65      catch (Exception ex) {
66        //Nothing to do because maybe called from adderror
67      }
68    }
69
70    public void UpdateHeartbeat(PeerInfo source) {
71      try {
72        Console.WriteLine("hb from {0}:{1}", source.IpAddress, source.Port);
73        DateTime now = DateTime.Now;
74        allPeers.AddOrUpdate(source, now, (k, v) => v = now);
75      }
76      catch (Exception ex) {
77        AddError("ContactServiceImpl.UpdateHeartbeat", ex);
78      }
79    }
80
81    private void CleanUpContactTable(object sender, ElapsedEventArgs e) {
82      lock (timerLock) {
83        DateTime deadline = DateTime.Now;
84        //collect items to remove
85        List<PeerInfo> itemsToDelete = new List<PeerInfo>();
86        foreach (PeerInfo pi in allPeers.Keys) {
87          DateTime tmp;
88          if (allPeers.TryGetValue(pi, out tmp)) {
89            //if (tmp.AddHours(1f) < deadline)
90            if (tmp.AddMinutes(1) < deadline)  //TODO
91                    {
92              //if (tmp < deadline.AddHours(1f)) {
93              itemsToDelete.Add(pi);
94            }
95          }
96        }
97        //remove items
98        foreach (PeerInfo pi in itemsToDelete) {
99          DateTime tmp;
100          allPeers.TryRemove(pi, out tmp);
101          Console.WriteLine(string.Format("Removed peer {0}:{1} from dictionary because last access was: {2}", pi.IpAddress, pi.Port, tmp));
102        }
103      }
104    }
105
106    private void AddError(string source, Exception ex) {
107      MakeLog(new PeerInfo() { ProblemInstance = "ContactServer  Error at " + source }, ex.Message);
108    }
109
110  }
111}
Note: See TracBrowser for help on using the repository browser.