Beispiel #1
0
        public static void MemCacheCommand(string[] args)
        {
            if (args.Length < 1)
            {
                Console.Error.WriteLine("Expected memcache sub-command");
                SetFailure();
                return;
            }

            string act = args[0].ToLower();

            switch (act)
            {
            case "create":
            {
                string mcname    = null;
                string mcschema  = null;
                int    mcsegsize = -1;
                EachArgument(args, 1,
                             new Action <string, string>(
                                 delegate(string key, string value)
                    {
                        key = key.ToLower();
                        switch (key)
                        {
                        case "name":
                            mcname = value;
                            break;

                        case "schema":
                            mcschema = value;
                            break;

                        case "segment":
                        case "segsize":
                        case "segmentsize":
                            mcsegsize = ParseCapacity(value);
                            break;
                        }
                    }));
                if (string.IsNullOrEmpty(mcname))
                {
                    Console.Error.WriteLine("Expected name=<MemCacheName>");
                    SetFailure();
                    return;
                }
                if (string.IsNullOrEmpty(mcschema))
                {
                    Console.Error.WriteLine("Expected schema=<schema>");
                    SetFailure();
                    return;
                }
                if (-1 != mcsegsize && mcsegsize < 1024)
                {
                    Console.Error.WriteLine("Error: segment={0} is too small", mcsegsize);
                    SetFailure();
                    return;
                }
                if (mcname.StartsWith("dfs://", StringComparison.OrdinalIgnoreCase))
                {
                    mcname = mcname.Substring(6);
                }
                {
                    string reason;
                    if (dfs.IsBadFilename(mcname, out reason))
                    {
                        Console.Error.WriteLine("MemCache cannot be named '{0}': {1}", mcname, reason);
                        SetFailure();
                        return;
                    }
                }
                dfs.DfsFile.ConfigMemCache cmc = new dfs.DfsFile.ConfigMemCache();
                cmc.MetaFileName = "mcm." + Surrogate.SafeTextPath(mcname) + ".mcm";
                cmc.Schema       = mcschema;
                List <int> offsets = new List <int>();
                cmc.RowLength = Surrogate.GetRecordInfo(mcschema, out cmc.KeyOffset, out cmc.KeyLength, offsets);

                /*if (0 == cmc.KeyOffset
                 *  && cmc.RowLength == cmc.KeyLength
                 *  && -1 == mcschema.IndexOf('['))
                 * {
                 *  Console.WriteLine("Note: no key was specified, the key is the entire row");
                 * }*/
                if (-1 == mcsegsize)
                {
                    const int defsegsize = 0x400 * 0x400 * 64;
                    cmc.SegmentSize = defsegsize - (defsegsize % cmc.RowLength);
                }
                else
                {
                    if (0 != (mcsegsize % cmc.RowLength))
                    {
                        Console.Error.WriteLine("Segment size must be a multiple of the row length");
                        Console.Error.WriteLine("Nearest segment size is {0} bytes",
                                                mcsegsize - (mcsegsize % cmc.RowLength));
                        SetFailure();
                        return;
                    }
                    cmc.SegmentSize = mcsegsize;
                }
                {
                    StringBuilder sbFieldOffsets = new StringBuilder();
                    foreach (int offset in offsets)
                    {
                        if (sbFieldOffsets.Length != 0)
                        {
                            sbFieldOffsets.Append(',');
                        }
                        sbFieldOffsets.Append(offset);
                    }
                    cmc.FieldOffsets = sbFieldOffsets.ToString();
                }
                dfs.DfsFile df = new dfs.DfsFile();
                df.Nodes     = new List <dfs.DfsFile.FileNode>(0);
                df.MemCache  = cmc;
                df.Name      = mcname;
                df.XFileType = DfsFileTypes.BINARY_RECT + "@" + cmc.RowLength;
                df.Size      = 0;
                dfs dc = LoadDfsConfig();
                {
                    dfs.DfsFile df2 = dc.FindAny(df.Name);
                    if (null != df2)
                    {
                        Console.Error.WriteLine("Error: a file named '{0}' already exists", df2.Name);
                        SetFailure();
                        return;
                    }
                }
                {
                    string          startmeta        = GetMemCacheMetaFileHeader(df);
                    string[]        slaves           = dc.Slaves.SlaveList.Split(';');
                    int             totalworkercount = dc.Blocks.TotalCount; // Subprocess_TotalPrime
                    StringBuilder[] permachine       = new StringBuilder[slaves.Length];
                    //byte[] HEADER = new byte[4];
                    //MySpace.DataMining.DistributedObjects.Entry.ToBytes(4, HEADER, 0);
                    for (int i = 0; i < permachine.Length; i++)
                    {
                        permachine[i] = new StringBuilder(256);
                    }
                    {
                        int si = -1;
                        for (int workerid = 0; workerid < totalworkercount; workerid++)
                        {
                            if (++si >= slaves.Length)
                            {
                                si = 0;
                            }
                            StringBuilder sb = permachine[si];
                            sb.AppendFormat("##{1}:{0}", Environment.NewLine, workerid);
                            // There's no segments, but write a dummy one for bookkeeping.
                            foreach (char snc in "MemCache_" + mcname + "_empty")
                            {
                                sb.Append(snc);
                            }
                            {
                                sb.Append(' ');

                                /*
                                 * StringBuilder newchunkpath = new StringBuilder(100);
                                 * newchunkpath.Append(Surrogate.NetworkPathForHost(slaves[si]));
                                 * newchunkpath.Append('\\');
                                 * */
                                // Make up a data node chunk name.
                                foreach (char ch in MakeMemCacheChunkName(mcname, workerid))
                                {
                                    //newchunkpath.Append(ch);
                                    sb.Append(ch);
                                }
                                // Write the empty chunk.
                                //System.IO.File.WriteAllBytes(newchunkpath.ToString(), HEADER);
                            }
                            //if (IsLastSegment) // true
                            {
                                sb.Append(' ');
                                string shexlen = string.Format("{0:x8}", 0);         // Zero-length!
                                for (int i = 0; i < shexlen.Length; i++)
                                {
                                    sb.Append(shexlen[i]);
                                }
                            }
                            sb.AppendLine();
                        }
                    }
                    for (int si = 0; si < slaves.Length; si++)
                    {
                        string slave = slaves[si];
                        string fp    = Surrogate.NetworkPathForHost(slave) + @"\" + cmc.MetaFileName;
                        using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fp))
                        {
                            sw.Write(startmeta);
                            sw.Write(permachine[si].ToString());
                        }
                    }
                }
                using (LockDfsMutex())
                {
                    dc = LoadDfsConfig();         // Load again in update lock.
                    {
                        dfs.DfsFile df2 = dc.FindAny(df.Name);
                        if (null != df2)
                        {
                            Console.Error.WriteLine("Error: a file named '{0}' already exists", df2.Name);
                            SetFailure();
                            return;
                        }
                    }
                    dc.Files.Add(df);
                    UpdateDfsXml(dc);
                }
                try
                {
                    // Need to commit it so that the empty chunks are in the metadata for bookkeeping.
                    // This has to be done after actually adding it to dfsxml.
                    MemCacheFlush(mcname);
                }
                catch (Exception e)
                {
                    try
                    {
                        MemCacheDelete(mcname, false);
                    }
                    catch
                    {
                    }
                    Console.Error.WriteLine("Error: unable to commit newly created MemCache '{0}'; because:{1}{2}",
                                            mcname, Environment.NewLine, e.ToString());
                    SetFailure();
                    return;
                }
                Console.WriteLine("Successfully created MemCache '{0}'", mcname);
            }
            break;

            case "delete":
            case "del":
            case "rm":
            {
                string mcname = null;
                EachArgument(args, 1,
                             new Action <string, string>(
                                 delegate(string key, string value)
                    {
                        key = key.ToLower();
                        switch (key)
                        {
                        case "name":
                            mcname = value;
                            break;
                        }
                    }));
                if (string.IsNullOrEmpty(mcname))
                {
                    Console.Error.WriteLine("Expected name=<MemCacheName>");
                    SetFailure();
                    return;
                }
                MemCacheDelete(mcname, true);
            }
            break;

            case "flush":
            case "commit":
            {
                string mcname = null;
                EachArgument(args, 1,
                             new Action <string, string>(
                                 delegate(string key, string value)
                    {
                        key = key.ToLower();
                        switch (key)
                        {
                        case "name":
                            mcname = value;
                            break;
                        }
                    }));
                if (string.IsNullOrEmpty(mcname))
                {
                    Console.Error.WriteLine("Expected name=<MemCacheName>");
                    SetFailure();
                    return;
                }
                try
                {
                    MemCacheFlush(mcname);
                    Console.WriteLine("Done");
                }
                catch (Exception e)
                {
                    Console.WriteLine("    Commit was unsuccessful because: {0}", e.Message);
                    Console.WriteLine();
                    Console.Error.WriteLine(e.ToString());
                    SetFailure();
                    return;
                }
            }
            break;

            case "release":
            case "rollback":
            {
                string mcname = null;
                bool   force  = false;
                EachArgument(args, 1,
                             new Action <string, string>(
                                 delegate(string key, string value)
                    {
                        key = key.ToLower();
                        switch (key)
                        {
                        case "name":
                            mcname = value;
                            break;

                        case "-f":
                            force = true;
                            break;
                        }
                    }));
                if (string.IsNullOrEmpty(mcname))
                {
                    Console.Error.WriteLine("Expected name=<MemCacheName>");
                    SetFailure();
                    return;
                }
                try
                {
                    MemCacheRelease(mcname, force);
                    Console.WriteLine("Done");
                }
                catch (Exception e)
                {
                    string exception = e.ToString();
                    if (-1 != exception.IndexOf("MemCacheWarning"))
                    {
                        Console.WriteLine("Warning: " + exception);
                    }
                    else
                    {
                        Console.Error.WriteLine(exception);
                        string ioe = "InvalidOperationException:";
                        if (!force && -1 != exception.IndexOf(ioe))
                        {
                            try
                            {
                                string emsg = exception.Substring(exception.IndexOf(ioe) + ioe.Length)
                                              .Split('\r', '\n')[0].Trim();
                                System.Threading.Thread.Sleep(100);
                                Console.WriteLine();
                                Console.WriteLine("{0}{2}{1}",
                                                  false ? "\u00014" : "", false ? "\u00010" : "",
                                                  emsg);
                                System.Threading.Thread.Sleep(100);
                            }
                            catch
                            {
                            }
                            Console.Error.WriteLine("Use rollback -f followed by killall to force rollback");
                        }
                        SetFailure();
                        return;
                    }
                }
            }
            break;

            case "load":
            {
                string mcname = null;
                EachArgument(args, 1,
                             new Action <string, string>(
                                 delegate(string key, string value)
                    {
                        key = key.ToLower();
                        switch (key)
                        {
                        case "name":
                            mcname = value;
                            break;
                        }
                    }));
                if (string.IsNullOrEmpty(mcname))
                {
                    Console.Error.WriteLine("Expected name=<MemCacheName>");
                    SetFailure();
                    return;
                }
                MemCacheLoad(mcname);
                Console.WriteLine("Done");
            }
            break;

            case "info":
            case "information":
            {
                string mcname = null;
                EachArgument(args, 1,
                             new Action <string, string>(
                                 delegate(string key, string value)
                    {
                        key = key.ToLower();
                        switch (key)
                        {
                        case "name":
                            mcname = value;
                            break;
                        }
                    }));
                if (string.IsNullOrEmpty(mcname))
                {
                    Console.Error.WriteLine("Expected name=<MemCacheName>");
                    SetFailure();
                    return;
                }

                if (mcname.StartsWith("dfs://", StringComparison.OrdinalIgnoreCase))
                {
                    mcname = mcname.Substring(6);
                }
                dfs         dc = LoadDfsConfig();
                dfs.DfsFile df = dc.FindAny(mcname);
                if (null == df || df.MemCache == null)
                {
                    Console.Error.WriteLine("Error: '{0}' is not a MemCache", (null == df ? mcname : df.Name));
                    SetFailure();
                    return;
                }

                Console.WriteLine("  MemCache:      {0}", df.Name);
                Console.WriteLine("  Segment size:  {0} ({1})",
                                  GetFriendlyByteSize(df.MemCache.SegmentSize),
                                  df.MemCache.SegmentSize);
                Console.WriteLine("  Schema:        {0}", df.MemCache.Schema);
                Console.WriteLine("  Row Length:    {0}", df.MemCache.RowLength);
                Console.WriteLine("  Key Offset:    {0}", df.MemCache.KeyOffset);
                Console.WriteLine("  Key Length:    {0}", df.MemCache.KeyLength);
            }
            break;

            default:
                Console.Error.WriteLine("No such sub-command for memcache: {0}", act);
                SetFailure();
                return;
            }
        }