Example #1
0
        private bool TryBecomeConductor()
        {
            try {
                _writeSeriesLocks.Add(_conductorLock, Pid);
            } catch (ArgumentException) {
            }
            long conductorPid;

            if (_writeSeriesLocks.TryGetValue(_conductorLock, out conductorPid))
            {
                if (conductorPid == Pid)
                {
                    LogConductorPid(Pid);
                    return(true);
                }
                if (IsProcessAlive(conductorPid))
                {
                    return(false);
                }
                // TODO need atomic CAS operations on dictionary, however in this case it is not very important, we should not open/close repos many times
                _writeSeriesLocks[_conductorLock] = Pid;
                LogConductorPid(Pid);
                return(true);
            }
            throw new ApplicationException("Value must exist");
        }
Example #2
0
        private async Task Upgrade <K, V>(UUID seriesId, PersistentSeries <K, V> series)
        {
            if (!series.IsWriter)
            {
                try {
                    _writeSeriesLocks.Add(seriesId, Pid);
                    series.IsWriter = true;
                    LogAcquireLock(seriesId, series.Version);
                    return;
                } catch (ArgumentException) { }
            }
            while (true)
            {
                // wait if a writer from the same repo releases lock
                var released = await series.LockReleaseEvent.WaitAsync(1000);

                if (released)
                {
                    try {
                        // TODO TryAdd atomic method
                        _writeSeriesLocks.Add(seriesId, Pid);
                        series.IsWriter = true;
                        LogAcquireLock(seriesId, series.Version);
                        break;
                    } catch (ArgumentException) {
                        Trace.WriteLine("Could not upgrade after lock release, some one jumped ahead of us");
                    }
                }
                else
                {
                    int pid;
                    if (_writeSeriesLocks.TryGetValue(seriesId, out pid))
                    {
                        try {
                            Process.GetProcessById(pid & ((1 << 16) - 1));
                            Trace.TraceWarning("Tried to steal a lock but the owner process was alive.");
                        } catch (ArgumentException) {
                            // pid is not running anymore, steal lock
                            Trace.TraceWarning($"Current process {Pid} has stolen a lock left by a dead process {pid}. If you see this often then dispose SeriesRepository properly before application exit.");
                            _writeSeriesLocks[seriesId] = Pid;
                            series.IsWriter             = true;
                            LogAcquireLock(seriesId, series.Version);
                            break;
                        }
                    }
                }
            }
        }