예제 #1
0
 /// <summary>
 /// Gets a topology by version. Returns null if topology history storage doesn't contain
 /// specified topology version (history currently keeps the last 1000 snapshots).
 /// </summary>
 /// <param name="version">Topology version.</param>
 /// <returns>Collection of Ignite nodes which represented by specified topology version,
 /// if it is present in history storage, {@code null} otherwise.</returns>
 /// <exception cref="IgniteException">If underlying SPI implementation does not support
 /// topology history. Currently only {@link org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi}
 /// supports topology history.</exception>
 internal ICollection <IClusterNode> Topology(long version)
 {
     return(DoOutInOp(OpTopology, writer => writer.WriteLong(version),
                      input => IgniteUtils.ReadNodes(Marshaller.StartUnmarshal(input))));
 }
예제 #2
0
        /// <summary>
        /// Starts Ignite with given configuration.
        /// </summary>
        /// <returns>Started Ignite.</returns>
        public unsafe static IIgnite Start(IgniteConfiguration cfg)
        {
            IgniteArgumentCheck.NotNull(cfg, "cfg");

            // Copy configuration to avoid changes to user-provided instance.
            IgniteConfigurationEx cfgEx = cfg as IgniteConfigurationEx;

            cfg = cfgEx == null ? new IgniteConfiguration(cfg) : new IgniteConfigurationEx(cfgEx);

            // Set default Spring config if needed.
            if (cfg.SpringConfigUrl == null)
            {
                cfg.SpringConfigUrl = DefaultCfg;
            }

            lock (SyncRoot)
            {
                // 1. Check GC settings.
                CheckServerGc(cfg);

                // 2. Create context.
                IgniteUtils.LoadDlls(cfg.JvmDllPath);

                var cbs = new UnmanagedCallbacks();

                IgniteManager.CreateJvmContext(cfg, cbs);

                var gridName = cfgEx != null ? cfgEx.GridName : null;

                var cfgPath = Environment.GetEnvironmentVariable(EnvIgniteSpringConfigUrlPrefix) +
                              (cfg.SpringConfigUrl ?? DefaultCfg);

                // 3. Create startup object which will guide us through the rest of the process.
                _startup = new Startup(cfg, cbs);

                IUnmanagedTarget interopProc = null;

                try
                {
                    // 4. Initiate Ignite start.
                    UU.IgnitionStart(cbs.Context, cfgPath, gridName, ClientMode);

                    // 5. At this point start routine is finished. We expect STARTUP object to have all necessary data.
                    var node = _startup.Ignite;
                    interopProc = node.InteropProcessor;

                    // 6. On-start callback (notify lifecycle components).
                    node.OnStart();

                    Nodes[new NodeKey(_startup.Name)] = node;

                    return(node);
                }
                catch (Exception)
                {
                    // 1. Perform keys cleanup.
                    string name = _startup.Name;

                    if (name != null)
                    {
                        NodeKey key = new NodeKey(name);

                        if (Nodes.ContainsKey(key))
                        {
                            Nodes.Remove(key);
                        }
                    }

                    // 2. Stop Ignite node if it was started.
                    if (interopProc != null)
                    {
                        UU.IgnitionStop(interopProc.Context, gridName, true);
                    }

                    // 3. Throw error further (use startup error if exists because it is more precise).
                    if (_startup.Error != null)
                    {
                        throw _startup.Error;
                    }

                    throw;
                }
                finally
                {
                    _startup = null;

                    if (interopProc != null)
                    {
                        UU.ProcessorReleaseStart(interopProc);
                    }
                }
            }
        }
예제 #3
0
 /// <summary>
 /// Creates an object and sets the properties.
 /// </summary>
 /// <param name="reader">Reader.</param>
 /// <returns>Resulting object.</returns>
 private static T CreateObject <T>(IBinaryRawReader reader)
 {
     return(IgniteUtils.CreateInstance <T>(reader.ReadString(),
                                           reader.ReadDictionaryAsGeneric <string, object>()));
 }
예제 #4
0
 /// <summary>
 /// Gets the custom configuration.
 /// </summary>
 private static IgniteConfiguration GetCustomConfig()
 {
     // CacheConfiguration is not tested here - see CacheConfigurationTest
     return(new IgniteConfiguration
     {
         DiscoverySpi = new TcpDiscoverySpi
         {
             NetworkTimeout = TimeSpan.FromSeconds(1),
             AckTimeout = TimeSpan.FromSeconds(2),
             MaxAckTimeout = TimeSpan.FromSeconds(3),
             SocketTimeout = TimeSpan.FromSeconds(4),
             JoinTimeout = TimeSpan.FromSeconds(5),
             IpFinder = new TcpDiscoveryStaticIpFinder
             {
                 Endpoints = new[] { "127.0.0.1:49900", "127.0.0.1:49901" }
             },
             ClientReconnectDisabled = true,
             ForceServerMode = true,
             IpFinderCleanFrequency = TimeSpan.FromMinutes(7),
             LocalAddress = "127.0.0.1",
             LocalPort = 49900,
             LocalPortRange = 13,
             ReconnectCount = 11,
             StatisticsPrintFrequency = TimeSpan.FromSeconds(20),
             ThreadPriority = 6,
             TopologyHistorySize = 1234567
         },
         IgniteInstanceName = "gridName1",
         IgniteHome = IgniteHome.Resolve(null),
         IncludedEventTypes = EventType.DiscoveryAll,
         MetricsExpireTime = TimeSpan.FromMinutes(7),
         MetricsHistorySize = 125,
         MetricsLogFrequency = TimeSpan.FromMinutes(8),
         MetricsUpdateFrequency = TimeSpan.FromMinutes(9),
         NetworkSendRetryCount = 54,
         NetworkTimeout = TimeSpan.FromMinutes(10),
         NetworkSendRetryDelay = TimeSpan.FromMinutes(11),
         WorkDirectory = Path.GetTempPath(),
         JvmOptions = TestUtils.TestJavaOptions(),
         JvmClasspath = TestUtils.CreateTestClasspath(),
         Localhost = "127.0.0.1",
         IsDaemon = false,
         IsLateAffinityAssignment = false,
         UserAttributes = Enumerable.Range(1, 10).ToDictionary(x => x.ToString(), x => (object)x),
         AtomicConfiguration = new AtomicConfiguration
         {
             CacheMode = CacheMode.Replicated,
             Backups = 2,
             AtomicSequenceReserveSize = 200
         },
         TransactionConfiguration = new TransactionConfiguration
         {
             DefaultTransactionConcurrency = TransactionConcurrency.Optimistic,
             DefaultTimeout = TimeSpan.FromSeconds(25),
             DefaultTransactionIsolation = TransactionIsolation.Serializable,
             PessimisticTransactionLogLinger = TimeSpan.FromHours(1),
             PessimisticTransactionLogSize = 240
         },
         CommunicationSpi = new TcpCommunicationSpi
         {
             LocalPort = 47501,
             MaxConnectTimeout = TimeSpan.FromSeconds(34),
             MessageQueueLimit = 15,
             ConnectTimeout = TimeSpan.FromSeconds(17),
             IdleConnectionTimeout = TimeSpan.FromSeconds(19),
             SelectorsCount = 8,
             ReconnectCount = 33,
             SocketReceiveBufferSize = 512,
             AckSendThreshold = 99,
             DirectBuffer = false,
             DirectSendBuffer = true,
             LocalPortRange = 45,
             LocalAddress = "127.0.0.1",
             TcpNoDelay = false,
             SlowClientQueueLimit = 98,
             SocketSendBufferSize = 2045,
             UnacknowledgedMessagesBufferSize = 3450
         },
         FailureDetectionTimeout = TimeSpan.FromSeconds(3.5),
         ClientFailureDetectionTimeout = TimeSpan.FromMinutes(12.3),
         LongQueryWarningTimeout = TimeSpan.FromMinutes(1.23),
         IsActiveOnStart = true,
         BinaryConfiguration = new BinaryConfiguration
         {
             CompactFooter = false,
             TypeConfigurations = new[]
             {
                 new BinaryTypeConfiguration
                 {
                     TypeName = "myType",
                     IsEnum = true,
                     AffinityKeyFieldName = "affKey",
                     KeepDeserialized = false
                 }
             }
         },
         // Skip cache check because with persistence the grid is not active by default.
         PluginConfigurations = new[] { new TestIgnitePluginConfiguration {
                                            SkipCacheCheck = true
                                        } },
         EventStorageSpi = new MemoryEventStorageSpi
         {
             ExpirationTimeout = TimeSpan.FromSeconds(5),
             MaxEventCount = 10
         },
         PublicThreadPoolSize = 3,
         StripedThreadPoolSize = 5,
         ServiceThreadPoolSize = 6,
         SystemThreadPoolSize = 7,
         AsyncCallbackThreadPoolSize = 8,
         ManagementThreadPoolSize = 9,
         DataStreamerThreadPoolSize = 10,
         UtilityCacheThreadPoolSize = 11,
         QueryThreadPoolSize = 12,
         SqlConnectorConfiguration = new SqlConnectorConfiguration
         {
             Host = "127.0.0.2",
             Port = 1081,
             PortRange = 3,
             SocketReceiveBufferSize = 2048,
             MaxOpenCursorsPerConnection = 5,
             ThreadPoolSize = 4,
             TcpNoDelay = false,
             SocketSendBufferSize = 4096
         },
         ConsistentId = new MyConsistentId {
             Data = "abc"
         },
         DataStorageConfiguration = new DataStorageConfiguration
         {
             AlwaysWriteFullPages = true,
             CheckpointFrequency = TimeSpan.FromSeconds(25),
             CheckpointPageBufferSize = 28 * 1024 * 1024,
             CheckpointThreads = 2,
             LockWaitTime = TimeSpan.FromSeconds(5),
             StoragePath = Path.GetTempPath(),
             WalThreadLocalBufferSize = 64 * 1024,
             WalArchivePath = Path.GetTempPath(),
             WalFlushFrequency = TimeSpan.FromSeconds(3),
             WalFsyncDelayNanos = 3,
             WalHistorySize = 10,
             WalMode = Configuration.WalMode.LogOnly,
             WalRecordIteratorBufferSize = 32 * 1024 * 1024,
             WalSegments = 6,
             WalSegmentSize = 5 * 1024 * 1024,
             WalPath = Path.GetTempPath(),
             MetricsEnabled = true,
             MetricsSubIntervalCount = 7,
             MetricsRateTimeInterval = TimeSpan.FromSeconds(9),
             CheckpointWriteOrder = Configuration.CheckpointWriteOrder.Random,
             WriteThrottlingEnabled = true,
             SystemRegionInitialSize = 64 * 1024 * 1024,
             SystemRegionMaxSize = 128 * 1024 * 1024,
             ConcurrencyLevel = 1,
             PageSize = 8 * 1024,
             DefaultDataRegionConfiguration = new DataRegionConfiguration
             {
                 Name = "reg1",
                 EmptyPagesPoolSize = 50,
                 EvictionThreshold = 0.8,
                 InitialSize = 100 * 1024 * 1024,
                 MaxSize = 150 * 1024 * 1024,
                 MetricsEnabled = true,
                 PageEvictionMode = Configuration.DataPageEvictionMode.Random2Lru,
                 PersistenceEnabled = false,
                 MetricsRateTimeInterval = TimeSpan.FromMinutes(2),
                 MetricsSubIntervalCount = 6,
                 SwapPath = IgniteUtils.GetTempDirectoryName()
             },
             DataRegionConfigurations = new[]
             {
                 new DataRegionConfiguration
                 {
                     Name = "reg2",
                     EmptyPagesPoolSize = 51,
                     EvictionThreshold = 0.7,
                     InitialSize = 101 * 1024 * 1024,
                     MaxSize = 151 * 1024 * 1024,
                     MetricsEnabled = false,
                     PageEvictionMode = Configuration.DataPageEvictionMode.RandomLru,
                     PersistenceEnabled = false,
                     MetricsRateTimeInterval = TimeSpan.FromMinutes(3),
                     MetricsSubIntervalCount = 7,
                     SwapPath = IgniteUtils.GetTempDirectoryName()
                 }
             }
         }
     });
 }
예제 #5
0
 /** <inheritdoc /> */
 public virtual IFuture <TResult> GetFuture <TResult>()
 {
     throw IgniteUtils.GetAsyncModeDisabledException();
 }
예제 #6
0
        public void TestStructure()
        {
            for (int i = 1; i <= RepeatCnt; i++)
            {
                Console.WriteLine(">>> Iteration started: " + i);

                // 1. Generate and shuffle objects.
                IList <BranchedType> objs = new List <BranchedType>();

                for (int j = 0; j < 6 * ObjectsPerMode; j++)
                {
                    objs.Add(new BranchedType((j % 6) + 1));
                }

                objs = IgniteUtils.Shuffle(objs);

                // 2. Create new marshaller.
                BinaryTypeConfiguration typeCfg = new BinaryTypeConfiguration(typeof(BranchedType));

                BinaryConfiguration cfg = new BinaryConfiguration
                {
                    TypeConfigurations = new List <BinaryTypeConfiguration> {
                        typeCfg
                    }
                };

                Marshaller marsh = new Marshaller(cfg);

                // 3. Marshal all data and ensure deserialized object is fine.
                // Use single stream to test object offsets
                using (var stream = new BinaryHeapStream(128))
                {
                    var writer = marsh.StartMarshal(stream);

                    foreach (var obj in objs)
                    {
                        Console.WriteLine(">>> Write object [mode=" + obj.mode + ']');

                        writer.WriteObject(obj);
                    }

                    stream.Seek(0, SeekOrigin.Begin);

                    var reader = marsh.StartUnmarshal(stream);

                    foreach (var obj in objs)
                    {
                        var other = reader.ReadObject <BranchedType>();

                        Assert.IsTrue(obj.Equals(other));
                    }
                }

                Console.WriteLine();

                // 4. Ensure that all fields are recorded.
                var desc = marsh.GetDescriptor(typeof(BranchedType));

                CollectionAssert.AreEquivalent(new[] { "mode", "f2", "f3", "f4", "f5", "f6", "f7", "f8" },
                                               desc.WriterTypeStructure.FieldTypes.Keys);
            }
        }
예제 #7
0
        public void Map(PlatformMemoryStream stream)
        {
            IList <IClusterNode> subgrid;

            ClusterGroupImpl prj = (ClusterGroupImpl)_compute.ClusterGroup;

            var ignite = (Ignite)prj.Ignite;

            // 1. Unmarshal topology info if topology changed.
            var reader = prj.Marshaller.StartUnmarshal(stream);

            if (reader.ReadBoolean())
            {
                long topVer = reader.ReadLong();

                List <IClusterNode> nodes = new List <IClusterNode>(reader.ReadInt());

                int nodesCnt = reader.ReadInt();

                subgrid = new List <IClusterNode>(nodesCnt);

                for (int i = 0; i < nodesCnt; i++)
                {
                    IClusterNode node = ignite.GetNode(reader.ReadGuid());

                    nodes.Add(node);

                    if (reader.ReadBoolean())
                    {
                        subgrid.Add(node);
                    }
                }

                // Update parent projection to help other task callers avoid this overhead.
                // Note that there is a chance that topology changed even further and this update fails.
                // It means that some of subgrid nodes could have left the Grid. This is not critical
                // for us, because Java will handle it gracefully.
                prj.UpdateTopology(topVer, nodes);
            }
            else
            {
                IList <IClusterNode> nodes = prj.NodesNoRefresh();

                Debug.Assert(nodes != null, "At least one topology update should have occurred.");

                subgrid = IgniteUtils.Shuffle(nodes);
            }

            // 2. Perform map.
            IDictionary <IComputeJob <T>, IClusterNode> map;
            Exception err;

            try
            {
                map = _task.Map(subgrid, _arg);

                err = null;
            }
            catch (Exception e)
            {
                map = null;

                err = e;

                // Java can receive another exception in case of marshalling failure but it is not important.
                Finish(default(TR), e);
            }

            // 3. Write map result to the output stream.
            stream.Reset();
            BinaryWriter writer = prj.Marshaller.StartMarshal(stream);

            try
            {
                if (err == null)
                {
                    writer.WriteBoolean(true); // Success flag.

                    if (map == null)
                    {
                        writer.WriteBoolean(false); // Map produced no result.
                    }
                    else
                    {
                        writer.WriteBoolean(true); // Map produced result.

                        _jobHandles = WriteJobs(writer, map);
                    }
                }
                else
                {
                    writer.WriteBoolean(false); // Map failed.

                    // Write error as string because it is not important for Java, we need only to print
                    // a message in the log.
                    writer.WriteString("Map step failed [errType=" + err.GetType().Name +
                                       ", errMsg=" + err.Message + ']');
                }
            }
            catch (Exception e)
            {
                // Something went wrong during marshaling.
                Finish(default(TR), e);

                stream.Reset();

                writer.WriteBoolean(false);    // Map failed.
                writer.WriteString(e.Message); // Write error message.
            }
            finally
            {
                prj.Marshaller.FinishMarshal(writer);
            }
        }
예제 #8
0
 /** <inheritdoc /> */
 public IEnumerable <ICacheEntry <TK, TV> > GetLocalEntries(CachePeekMode[] peekModes)
 {
     return(new CacheEnumerable <TK, TV>(this, IgniteUtils.EncodePeekModes(peekModes)));
 }
예제 #9
0
        /** <inheritDoc /> */
        public Task <int> GetSizeAsync(params CachePeekMode[] modes)
        {
            var modes0 = IgniteUtils.EncodePeekModes(modes);

            return(DoOutOpAsync <int>(CacheOp.SizeAsync, w => w.WriteInt(modes0)));
        }
예제 #10
0
        /// <summary>
        /// Starts Ignite with given configuration.
        /// </summary>
        /// <returns>Started Ignite.</returns>
        public static IIgnite Start(IgniteConfiguration cfg)
        {
            IgniteArgumentCheck.NotNull(cfg, "cfg");

            cfg = new IgniteConfiguration(cfg);  // Create a copy so that config can be modified and reused.

            lock (SyncRoot)
            {
                // 0. Init logger
                var log = cfg.Logger ?? new JavaLogger();

                log.Debug("Starting Ignite.NET " + Assembly.GetExecutingAssembly().GetName().Version);

                // 1. Check GC settings.
                CheckServerGc(cfg, log);

                // 2. Create context.
                IgniteUtils.LoadDlls(cfg.JvmDllPath, log);

                var cbs = IgniteManager.CreateJvmContext(cfg, log);
                var env = cbs.Jvm.AttachCurrentThread();
                log.Debug("JVM started.");

                var gridName = cfg.IgniteInstanceName;

                if (cfg.AutoGenerateIgniteInstanceName)
                {
                    gridName = (gridName ?? "ignite-instance-") + Guid.NewGuid();
                }

                // 3. Create startup object which will guide us through the rest of the process.
                _startup = new Startup(cfg, cbs);

                PlatformJniTarget interopProc = null;

                try
                {
                    // 4. Initiate Ignite start.
                    UU.IgnitionStart(env, cfg.SpringConfigUrl, gridName, ClientMode, cfg.Logger != null, cbs.IgniteId,
                                     cfg.RedirectJavaConsoleOutput);

                    // 5. At this point start routine is finished. We expect STARTUP object to have all necessary data.
                    var node = _startup.Ignite;
                    interopProc = (PlatformJniTarget)node.InteropProcessor;

                    var javaLogger = log as JavaLogger;
                    if (javaLogger != null)
                    {
                        javaLogger.SetIgnite(node);
                    }

                    // 6. On-start callback (notify lifecycle components).
                    node.OnStart();

                    Nodes[new NodeKey(_startup.Name)] = node;

                    return(node);
                }
                catch (Exception ex)
                {
                    // 1. Perform keys cleanup.
                    string name = _startup.Name;

                    if (name != null)
                    {
                        NodeKey key = new NodeKey(name);

                        if (Nodes.ContainsKey(key))
                        {
                            Nodes.Remove(key);
                        }
                    }

                    // 2. Stop Ignite node if it was started.
                    if (interopProc != null)
                    {
                        UU.IgnitionStop(gridName, true);
                    }

                    // 3. Throw error further (use startup error if exists because it is more precise).
                    if (_startup.Error != null)
                    {
                        // Wrap in a new exception to preserve original stack trace.
                        throw new IgniteException("Failed to start Ignite.NET, check inner exception for details",
                                                  _startup.Error);
                    }

                    var jex = ex as JavaException;

                    if (jex == null)
                    {
                        throw;
                    }

                    throw ExceptionUtils.GetException(null, jex);
                }
                finally
                {
                    var ignite = _startup.Ignite;

                    _startup = null;

                    if (ignite != null)
                    {
                        ignite.ProcessorReleaseStart();
                    }
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Starts Ignite with given configuration.
        /// </summary>
        /// <returns>Started Ignite.</returns>
        public static unsafe IIgnite Start(IgniteConfiguration cfg)
        {
            IgniteArgumentCheck.NotNull(cfg, "cfg");

            lock (SyncRoot)
            {
                // 0. Init logger
                var log = cfg.Logger ?? new JavaLogger();

                log.Debug("Starting Ignite.NET " + Assembly.GetExecutingAssembly().GetName().Version);

                // 1. Check GC settings.
                CheckServerGc(cfg, log);

                // 2. Create context.
                IgniteUtils.LoadDlls(cfg.JvmDllPath, log);

                var cbs = new UnmanagedCallbacks(log);

                IgniteManager.CreateJvmContext(cfg, cbs, log);
                log.Debug("JVM started.");

                var gridName = cfg.IgniteInstanceName;

                // 3. Create startup object which will guide us through the rest of the process.
                _startup = new Startup(cfg, cbs);

                IUnmanagedTarget interopProc = null;

                try
                {
                    // 4. Initiate Ignite start.
                    UU.IgnitionStart(cbs.Context, cfg.SpringConfigUrl, gridName, ClientMode, cfg.Logger != null);


                    // 5. At this point start routine is finished. We expect STARTUP object to have all necessary data.
                    var node = _startup.Ignite;
                    interopProc = node.InteropProcessor;

                    var javaLogger = log as JavaLogger;
                    if (javaLogger != null)
                    {
                        javaLogger.SetProcessor(interopProc);
                    }

                    // 6. On-start callback (notify lifecycle components).
                    node.OnStart();

                    Nodes[new NodeKey(_startup.Name)] = node;

                    return(node);
                }
                catch (Exception)
                {
                    // 1. Perform keys cleanup.
                    string name = _startup.Name;

                    if (name != null)
                    {
                        NodeKey key = new NodeKey(name);

                        if (Nodes.ContainsKey(key))
                        {
                            Nodes.Remove(key);
                        }
                    }

                    // 2. Stop Ignite node if it was started.
                    if (interopProc != null)
                    {
                        UU.IgnitionStop(interopProc.Context, gridName, true);
                    }

                    // 3. Throw error further (use startup error if exists because it is more precise).
                    if (_startup.Error != null)
                    {
                        // Wrap in a new exception to preserve original stack trace.
                        throw new IgniteException("Failed to start Ignite.NET, check inner exception for details",
                                                  _startup.Error);
                    }

                    throw;
                }
                finally
                {
                    _startup = null;

                    if (interopProc != null)
                    {
                        UU.ProcessorReleaseStart(interopProc);
                    }
                }
            }
        }
예제 #12
0
 /// <summary>
 /// Gets the name of the temporary directory.
 /// </summary>
 public static string GetTempDirectoryName()
 {
     return(IgniteUtils.GetTempDirectoryName());
 }
 /// <summary>
 /// Creates an instance according to type name and properties.
 /// </summary>
 public T CreateInstance <T>()
 {
     return(IgniteUtils.CreateInstance <T>(TypeName, Properties));
 }
예제 #14
0
        static UnmanagedUtils()
        {
            var platform = Environment.Is64BitProcess ? "x64" : "x86";

            var resName = string.Format("{0}.{1}", platform, IgniteUtils.FileIgniteJniDll);

            var path = IgniteUtils.UnpackEmbeddedResource(resName, IgniteUtils.FileIgniteJniDll);

            var ptr = NativeMethods.LoadLibrary(path);

            if (ptr == IntPtr.Zero)
            {
                var err = Marshal.GetLastWin32Error();

                throw new IgniteException(string.Format("Failed to load {0} from {1}: [{2}]",
                                                        IgniteUtils.FileIgniteJniDll, path, IgniteUtils.FormatWin32Error(err)));
            }

            AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;

            JNI.SetConsoleHandler(UnmanagedCallbacks.ConsoleWriteHandler);
        }
예제 #15
0
 public void SetUp()
 {
     _tempFolder = IgniteUtils.GetTempDirectoryName();
 }
예제 #16
0
 /// <summary>
 /// Reads nodes from stream.
 /// </summary>
 private IList <IClusterNode> ReadNodes(IBinaryStream reader)
 {
     return(IgniteUtils.ReadNodes(Marshaller.StartUnmarshal(reader, _keepBinary)));
 }