Skip to content

Examples

Query example

using kx;
using Kx.Sapi;
using Kx.Sapi.Constants;

namespace Examples
{
    /// <summary>
    /// This program provides a basic example for executing commands using the SDK.
    /// </summary>
    internal class Program
    {
        private const string logCategory = "C# Example";

        private static void Main()
        {
            // Register the C# log method with the Kxs SDK.
            Kxs.RegisterLogHandler(LogMessage);

            // Create Kxs instance
            Kxs kxs = new();

            // Set up the connection properties
            SapiConfig sapiConfig = new()
            {
                // Specify the instance name
                InstanceName = "your-instance-name",
                // Specify the discovery node
                DiscoveryHosts = ["your-discovery-node.com:20000"],
                // Specify the retry policy
                RetryPolicy = new RetryPolicy(10, 20000, 1000, 1.5f),
                // Specify the listen ports
                ListenPorts = "10000-10200"
            };

            // Validate connection
            if (!kxs.Connect(sapiConfig))
            {
                LogMessage(LogLevel.Error, logCategory, "Unable to connect!");
                return;
            }

            LogMessage(LogLevel.Informational, logCategory, "Connected to server!");

            // Creates a c.Dict that will be sent to the server and displays the result
            CreateDict(kxs);

            // Creates a c.Flip that will be sent to the server and displays the result
            CreateFlip(kxs);
        }

        /// <summary>
        /// Creates a c.Dict object that gets send to the server.
        /// The server response will be displayed.
        /// </summary>
        /// <param name="kxs">Kxs connection handle</param>
        public static void CreateDict(Kxs kxs)
        {
            string[] keys = { "query" };
            object[] values = { "(`a`b`c)!(1 2 3)".ToCharArray() };

            c.Dict request = new(keys, values);

            KxsResponse response = new();

            // Send the command to the server
            bool result = kxs.Execute(".kxs.execute", request, null, true, null, response);

            if (result && response.RC == (short)RC.Ok)
            {
                c.Dict dict = (c.Dict)response.Payload;

                // Parse the header values
                string[] responseHeaders = dict.x as string[] ?? Array.Empty<string>();

                // Parse the response values
                long[]? responseValues = dict.y as long[];

                // Loop through all values
                for (int i = 0; i < responseHeaders.Length; i++)
                {
                    LogMessage(LogLevel.Informational, logCategory,
                        $"Name={responseHeaders[i]} Value={responseValues?[i]}");
                }
            }
            else
            {
                LogMessage(LogLevel.Error, logCategory, $"RC code was not Ok, RC={response.RC}");
            }
        }

        /// <summary>
        /// Creates a c.Flip object that gets send to the server.
        /// The server response will be displayed.
        /// </summary>
        /// <param name="kxs">Kxs connection handle</param>
        public static void CreateFlip(Kxs kxs)
        {
            string[] keys = { "query" };
            object[] values = { "10#enlist (`a`b`c)!(1 2 3)".ToCharArray() };

            c.Dict request = new(keys, values);

            KxsResponse response = new();

            // Send the command to the server
            bool result = kxs.Execute(".kxs.execute", request, null, true, null, response);

            if (result && response.RC == (short)RC.Ok)
            {
                c.Flip flip = (c.Flip)response.Payload;

                // Loop through all values
                for (int i = 0; i < flip.x.Length; i++)
                {
                    if (flip.y[i] is long[] responseValues)
                    {
                        foreach (long val in responseValues)
                        {
                            LogMessage(LogLevel.Verbose, logCategory, $"Name={flip.x[i]} Value={val}");
                        }
                    }
                }
            }
            else
            {
                LogMessage(LogLevel.Error, logCategory, $"RC code was not Ok, RC={response.RC}");
            }
        }

        /// <summary>
        /// Example log levels 
        /// </summary>
        private static class LogLevel
        {
            // Verbose log level
            public static int Verbose => 1;

            // Debug log level
            public static int Debug => 2;

            // Informational log level
            public static int Informational => 3;

            // Warning log level
            public static int Warning => 4;

            // Error log level
            public static int Error => 5;

            // Fatal log level
            public static int Fatal => 6;
        }

        /// <summary>
        /// The Kxs SDK expects a log method that contains a <paramref name="logLevel"/> and <paramref name="logMessage"/>
        /// </summary>
        /// <param name="logLevel">Describes importance and urgency of the message</param>
        /// <param name="logCategory">Category of log message</param>
        /// <param name="logMessage">Message to log</param>
        public static void LogMessage(int logLevel = 1, string logCategory = "", string logMessage = "")
        {
            Console.WriteLine($"{logLevel} [{logCategory}] {logMessage}");
        }
    }
}

Publish example

using Kx.Sapi;
using Kx.Sapi.Constants;

namespace Examples
{
    internal class C : kx.c { } // Instance of kx.c in order to get access to the Serialize/Deserialize function

    /// <summary>
    /// This program provides a basic example for publishing data using the SDK.
    /// </summary>
    internal static class Program
    {
        private const string logCategory = "C# Example";

        private static void Main()
        {
            // Register the C# log method with the Kxs SDK.
            Kxs.RegisterLogHandler(LogMessage);

            // Create Kxs instance
            Kxs kxs = new();

            // Set up the connection properties
            SapiConfig sapiConfig = new()
            {
                // Specify the instance name
                InstanceName = "your-instance-name",
                // Specify the discovery node
                DiscoveryHosts = ["https://your-discovery-node.com:2379"],
                // Specify the retry policy
                RetryPolicy = new(10, 20000, 1000, 1.5f),
                // Configure publish properties
                RtConfig = new()
                {
                    ConfigPath = Path.Combine(Environment.CurrentDirectory, "rt"),
                    Dir = Path.Combine(Environment.CurrentDirectory, "rt"),
                    CaInfoFile = Path.Combine(Environment.CurrentDirectory, "ca-bundle.crt"),
                },
                // Specify the listen ports
                ListenPorts = "10000-10200"
            };

            // Start connection
            KxsResponse response = new();

            // Validate connection
            if (!kxs.Connect(sapiConfig, response))
            {
                LogMessage(LogLevel.Error, logCategory, "Unable to connect!");
                return;
            }

            LogMessage(LogLevel.Informational, logCategory, "Connected to server!");

            // Creates a c.Dict that will be sent to the server asynchronously
            PublishData(kxs);

            // Creates a c.Dict that will be sent to the server synchronously
            RetryPolicy retryPolicy = new()
            {
                MaxAttempts = 3,
                RetryInterval = 100,
                RetryScaling = 1,
                Timeout = 5000
            };

            PublishData(kxs, retryPolicy);
        }

        /// <summary>
        /// Creates a c.Dict object that gets send to the server.
        /// The server response will be displayed.
        /// </summary>
        /// <param name="kxs">Kxs connection handle</param>
        /// <param name="retryPolicy">Optional retry policy. Specifying a retry policy will turn the publish call into a synchronous operation</param>
        private static void PublishData(Kxs kxs, RetryPolicy? retryPolicy = null)
        {
            KxsResponse response = new();

            IntPtr publisher = kxs.RegisterPublisher("feed1", response);
            if (publisher != IntPtr.Zero)
            {
                for (int i = 0; i < 100; i++)
                {
                    Dictionary<string, object> data = new Dictionary<string, object>
                    {
                        {"sensorId", 12345},
                        {"sensorReading", i},
                        {"timestamp", DateTime.Now}
                    };

                    kx.c.Dict pubData = new(data.Keys.ToArray(), data.Values.ToArray());

                    if (!kxs.Publish(publisher, 1, pubData, null, retryPolicy, response))
                    {
                        Console.WriteLine($"Publish failed, RC={response.RC} AC={response.AC} AI={response.AI}");
                    }
                }

                kxs.UnregisterPublisher(publisher);
            }
        }

        /// <summary>
        /// Example log levels 
        /// </summary>
        private static class LogLevel
        {
            // Verbose log level
            public static int Verbose => 1;

            // Debug log level
            public static int Debug => 2;

            // Informational log level
            public static int Informational => 3;

            // Warning log level
            public static int Warning => 4;

            // Error log level
            public static int Error => 5;

            // Fatal log level
            public static int Fatal => 6;
        }

        /// <summary>
        /// The Kxs SDK expects a log method that contains a <paramref name="logLevel"/> and <paramref name="logMessage"/>
        /// </summary>
        /// <param name="logLevel">Describes importance and urgency of the message</param>
        /// <param name="logCategory">Category of log message</param>
        /// <param name="logMessage">Message to log</param>
        public static void LogMessage(int logLevel = 1, string logCategory = "", string logMessage = "")
        {
            Console.WriteLine($"{logLevel} [{logCategory}] {logMessage}");
        }
    }
}

MQ example

using Kx.Sapi;

namespace Examples
{
    /// <summary>
    /// This program provides a basic example for executing commands using the SDK.
    /// </summary>
    internal class Program
    {
        private static Kxs? kxs;

        private const string logCategory = "C# Example";

        private static void Main()
        {
            // Register the C# log method with the Kxs SDK.
            Kxs.RegisterLogHandler(LogMessage);

            // Create Kxs instance
            kxs = new();

            // Set up the connection properties
            SapiConfig sapiConfig = new()
            {
                // Specify the instance name
                InstanceName = "your-instance-name",
                // Specify the discovery node
                DiscoveryHosts = new[] { "https://your-discovery-node.com:2379" },
                // Specify the retry policy
                RetryPolicy = new RetryPolicy(10, 20000, 1000, 1.5f),
                // Set MQ worker thread count to 1
                MQWorkerThreadCount = 1,
                // Specify the listen ports
                ListenPorts = "10000-10200"
            };

            // Validate connection
            if (!kxs.Connect(sapiConfig))
            {
                LogMessage(LogLevel.Error, logCategory, "Unable to connect!");
                return;
            }

            LogMessage(LogLevel.Informational, logCategory, "Connected to server!");

            KxsResponse response = new();

            string queueName = "DistSD";

            kxs.RegisterQueueListener(queueName, ClientAckCallback, AckMode.Client, response);

            LogMessage( LogLevel.Informational, logCategory, $"RegisterQueueListener response, RC={response.RC} AC={response.AC} AI={response.AI}");

            // Waiting 1 minute for callbacks
            Thread.Sleep(60 * 1000);

            kxs.UnregisterQueueListener(queueName, response);

            LogMessage( LogLevel.Informational, logCategory, $"UnregisterQueueListener response, RC={response.RC} AC={response.AC} AI={response.AI}");
        }

        private static bool AutoAckCallback(IntPtr client, string queue, int id, KxsResponse response)
        {
            LogMessage(LogLevel.Informational, logCategory, $"Received ack, queue={queue} id={id} reqCorr={response.ReqCorr}");

            return true; // Acknowledge message
        }

        private static bool ClientAckCallback(IntPtr client, string queue, int id, KxsResponse response)
        {
            LogMessage(LogLevel.Informational, logCategory, $"Received ack, queue={queue} id={id} reqCorr={response.ReqCorr}");

            Kxs.AckQueue(client, queue, id); // Acknowledge message

            return true; // Return value has no effect.
        }

        /// <summary>
        /// Acknowledgement modes 
        /// </summary>
        private static class AckMode
        {
            // Acknowledgments are automatically send
            public static short Auto => 1;

            // Acknowledgments are sent by explicitly calling AckQueue
            public static short Client => 2;

            // Explicit acknowledgments are not expected by the server. A message is considered consumed upon transmission to the listener
            public static short None => 3;
        }

        /// <summary>
        /// Example log levels 
        /// </summary>
        private static class LogLevel
        {
            // Verbose log level
            public static int Verbose => 1;

            // Debug log level
            public static int Debug => 2;

            // Informational log level
            public static int Informational => 3;

            // Warning log level
            public static int Warning => 4;

            // Error log level
            public static int Error => 5;

            // Fatal log level
            public static int Fatal => 6;
        }

        /// <summary>
        /// The Kxs SDK expects a log method that contains a <paramref name="logLevel"/> and <paramref name="logMessage"/>
        /// </summary>
        /// <param name="logLevel">Describes importance and urgency of the message</param>
        /// <param name="logCategory">Category of log message</param>
        /// <param name="logMessage">Message to log</param>
        public static void LogMessage(int logLevel = 1, string logCategory = "", string logMessage = "")
        {
            Console.WriteLine($"{logLevel} [{logCategory}] {logMessage}");
        }
    }
}