Пример #1
0
        public Replicator(IDataStore destination, ReplicationBehavior behavior, bool addIdentityToDestination)
        {
            if (behavior != ReplicationBehavior.ReplicateAndDelete)
            {
                throw new NotSupportedException("Only ReplicateAndDelete is currently supported");
            }

            if (destination == null)
            {
                throw new ArgumentNullException();
            }

            Registrations = new Registrations();

            CreateIdentityFieldInReplicatedTable = addIdentityToDestination;

            Behavior      = behavior;
            m_destination = destination;

            ReplicationPeriod       = DefaultReplicationPeriod;
            MaxReplicationBatchSize = DefaultBatchSize;

            m_dataAvailable = new AutoResetEvent(false);

            m_typeCounts = new Dictionary <Type, int>();
            m_nameCounts = new Dictionary <string, int>();
        }
Пример #2
0
        void m_source_AfterInsert(object sender, EntityInsertArgs e)
        {
            // if we have an insert on a replicated entity, don't wait for the full period, let the replication proc know immediately

            // TODO: add preemption?
            bool shouldRaise = false;

            lock (Registrations)
            {
                if (Registrations.Contains(e.EntityName))
                {
                    shouldRaise = true;
                }
                else if (Registrations.Contains(e.Item.GetType()))
                {
                    shouldRaise = true;
                }
            }

            if (shouldRaise)
            {
                ThreadPool.QueueUserWorkItem(delegate
                {
                    m_dataAvailable.Set();
                });
            }
        }
Пример #3
0
        private bool DoReplicationForPriority(ReplicationPriority priority)
        {
            bool dataSent = false;

            // loop through all registered entities
            lock (Registrations)
            {
                foreach (var registration in Registrations.GetNameRegistrations(priority))
                {
                    var items = m_source.Select(registration.LocalName).Take(MaxReplicationBatchSize);

                    foreach (var item in items)
                    {
                        item.EntityName = registration.ReplicatedName;
                        m_destination.Insert(item);

                        item.EntityName = registration.LocalName;
                        m_source.Delete(item);

                        // increment the count
                        m_nameCounts[registration.LocalName]++;

                        dataSent = true;

                        // yield so we're not chewing up processor time
                        Thread.Sleep(0);
                    }
                }

                foreach (var registration in Registrations.GetTypeRegistrations(priority))
                {
                    var items = m_source.Select(registration.Type).Take(MaxReplicationBatchSize);

                    foreach (var item in items)
                    {
                        m_destination.Insert(item);

                        m_source.Delete(item);

                        // increment the count
                        m_typeCounts[registration.Type]++;

                        dataSent = true;

                        // yield so we're not chewing up processor time
                        Thread.Sleep(0);
                    }
                }

                return(dataSent);
            }
        }
Пример #4
0
        public void RegisterEntity(Type entityType, ReplicationPriority priority)
        {
            lock (Registrations)
            {
                Registrations.AddType(entityType, priority);

                lock (m_typeCounts)
                {
                    if (!m_typeCounts.ContainsKey(entityType))
                    {
                        m_typeCounts.Add(entityType, 0);
                    }
                }

                // TODO: look for failure and cache if it does (e.g. not connected scenarios)
                m_destination.AddType(entityType);
            }
        }
Пример #5
0
        public void RegisterEntity(string entityName, string replicatedName, ReplicationPriority priority)
        {
            lock (Registrations)
            {
                Registrations.AddName(entityName, replicatedName, priority);

                lock (m_nameCounts)
                {
                    if (!m_nameCounts.ContainsKey(entityName))
                    {
                        m_nameCounts.Add(entityName, 0);
                    }
                }

                // TODO: look for failure and cache if it does (e.g. not connected scenarios)
                var definition = m_source.DiscoverDynamicEntity(entityName);

                definition.EntityName = replicatedName;

                // the replicated entity cannot use the same auto-increment field as the local table or we'll end up with replication problems where local IDs don't match remote IDs
                if (CreateIdentityFieldInReplicatedTable)
                {
                    var existing = definition.Fields.KeyField;
                    if (existing != null)
                    {
                        existing.IsPrimaryKey = false;
                    }

                    definition.EntityAttribute.KeyScheme = KeyScheme.Identity;
                    definition.Fields.Add(new FieldAttribute("ReplID", System.Data.DbType.Int32, true), true);
                }
                else
                {
                    definition.EntityAttribute.KeyScheme = KeyScheme.None;
                }

                m_destination.RegisterDynamicEntity(definition, true);
            }
        }