예제 #1
0
        /// <summary>
        /// 队列数据 读文件
        /// </summary>
        /// <param name="node">消息队列节点</param>
        /// <param name="config">队列数据 读取配置</param>
        /// <param name="readerIndex">读文件编号</param>
        internal QueueReader(QueueNode node, Config.QueueReader config, int readerIndex)
        {
            Writer      = node.Writer;
            Node        = node;
            this.config = config ?? defaultConfig;
            this.config.Format();
            this.readerIndex = readerIndex;
            int isReader = 0;

            ++Writer.ReadCount;
            writerAppendIdentity = Writer.StatePacketIndex.Identity;
            try
            {
                if (checkStateFile())
                {
                    stateFileStream = new FileStream(stateFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 256, FileOptions.None);
                    stateFileStream.Seek(-stateBufferSize, SeekOrigin.End);
                    stateFileStream.Read(bigBuffer, 0, stateBufferSize);

                    fixed(byte *stateDataFixed = bigBuffer) Identity = *(ulong *)stateDataFixed;
                }
                else
                {
                    stateFileStream = new FileStream(stateFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, 256, FileOptions.None);
                }
                long fileIndex = 0;
                if (Writer.GetIndex(Identity, ref dataFileIdentity, ref fileIndex))
                {
                    writeIdentity     = Identity;
                    memoryEndIdentity = Identity + config.MemoryCacheNodeCount;
                    messages          = new MessageItem[(int)config.MemoryCacheNodeCount + QueueWriter.MaxPacketCount + 1];
                    if (Identity == writerAppendIdentity || loadFile(fileIndex))
                    {
                        isReader = 1;
                    }
                }
            }
            finally
            {
                if (isReader == 0)
                {
                    Dispose();
                }
            }
        }
예제 #2
0
        /// <summary>
        /// 设置已完成消息标识
        /// </summary>
        internal void SaveIdentity()
        {
            ulong identity = (ulong)Interlocked.Exchange(ref currentSetIdentity, 0L);

            if (identity > Identity && identity <= sendIdentity)
            {
                if (stateFileStream.Length >= QueueWriter.MaxStateFileSize)
                {
                    stateFileStream.Dispose();
                    stateFileStream = null;
                    FileInfo bakFile = new FileInfo(stateBackupFileName);
                    if (bakFile.Exists)
                    {
                        bakFile.Delete();
                    }
                    System.IO.File.Move(stateFileName, stateBackupFileName);
                    stateFileStream = new FileStream(stateFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, 256, FileOptions.None);
                }
                fixed(byte *stateDataFixed = bigBuffer) * (ulong *)stateDataFixed = identity;

                stateFileStream.Write(bigBuffer, 0, stateBufferSize);
                if (flushIdentityTime != Date.NowTime.Now)
                {
                    stateFileStream.Flush(true);
                    flushIdentityTime = Date.NowTime.Now;
                }

                if (isDisposed == 0)
                {
                    int endMessageIndex = messageIndex + (int)(uint)(identity - Identity);
                    if (endMessageIndex >= messages.Length)
                    {
                        endMessageIndex -= messages.Length;
                    }
                    do
                    {
                        messages[messageIndex].FreeBuffer();
                        if (++messageIndex == messages.Length)
                        {
                            messageIndex = 0;
                        }
                    }while (messageIndex != endMessageIndex);
                    Identity          = identity;
                    memoryEndIdentity = identity + config.MemoryCacheNodeCount;
                    if (writeIdentity < memoryEndIdentity && writeIdentity < writerAppendIdentity)
                    {
                        byte isReader = 0, isLoadFile = 0;
                        try
                        {
                            if (dataFileStream != null)
                            {
                                if (dataFileIdentity == writeIdentity)
                                {
                                    isLoadFile = 1;
                                    if (loadFile())
                                    {
                                        isReader = 1;
                                    }
                                }
                                else
                                {
                                    dataFileStream.Dispose();
                                    dataFileStream = null;
                                }
                            }
                            if (isLoadFile == 0)
                            {
                                long fileIndex = 0;
                                if (Writer.GetIndex(writeIdentity, ref dataFileIdentity, ref fileIndex) && loadFile(fileIndex))
                                {
                                    isReader = 1;
                                }
                            }
                        }
                        finally
                        {
                            if (isReader == 0)
                            {
                                Dispose();
                            }
                        }
                    }
                    if (onGetMessage != null && isDisposed == 0)
                    {
                        ReturnParameter returnParameter = new ReturnParameter {
                            IsDeSerializeStream = isGetMessageStream, Type = ReturnType.Success
                        };
                        ulong endIdentity = Math.Min(Identity + config.SendClientCount, writeIdentity);
                        while (sendIdentity != endIdentity)
                        {
                            returnParameter.Parameter = messages[sendMessageIndex].Data;
                            if (onGetMessage(returnParameter))
                            {
                                nextSendIndex();
                            }
                            else
                            {
                                onGetMessage = null;
                                return;
                            }
                        }
                    }
                }
            }
        }