/*
* This ScaleOut StateServer sample illustrates how to use Invocation Grid to
* perform a Parallel Method Invocation (PMI) operation.
* (Requires a ScaleOut Analytics Server license key)
*
* Copyright 2013 ScaleOut Software, Inc.
*
* LICENSE AND DISCLAIMER
* ----------------------
* This material contains sample programming source code ("Sample Code").
* ScaleOut Software, Inc. (SSI) grants you a nonexclusive license to compile,
* link, run, display, reproduce, and prepare derivative works of
* this Sample Code. The Sample Code has not been thoroughly
* tested under all conditions. SSI, therefore, does not guarantee
* or imply its reliability, serviceability, or function. SSI
* provides no support services for the Sample Code.
*
* All Sample Code contained herein is provided to you "AS IS" without
* any warranties of any kind. THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGMENT ARE EXPRESSLY
* DISCLAIMED. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED
* WARRANTIES, SO THE ABOVE EXCLUSIONS MAY NOT APPLY TO YOU. IN NO
* EVENT WILL SSI BE LIABLE TO ANY PARTY FOR ANY DIRECT, INDIRECT,
* SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY USE OF THE SAMPLE CODE
* INCLUDING, WITHOUT LIMITATION, ANY LOST PROFITS, BUSINESS
* INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON YOUR INFORMATION
* HANDLING SYSTEM OR OTHERWISE, EVEN IF WE ARE EXPRESSLY ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Collections;
using Soss.Client;
namespace SOSS.InvocationGridSample
{
class Program
{
const string _gridName = "MyGrid";
const string _cacheName = "MyCache";
/// <summary>
/// Uses a NamedCache.Invoke() call to concatentate all strings stored in a distributed, in-memory
/// datagrid in parallel using map-reduce style semantics, optionally capitalizing the result. An
/// "invocation grid" is used to automatically deploy and run eval/merge methods on all hosts in
/// the ScaleOut StateSever farm.
/// </summary>
static void Main(string[] args)
{
NamedCache cache = CacheFactory.GetCache(_cacheName);
cache.Clear();
// Use the NamedCache to add 1000 string objects to the in-memory datagrid:
for (int i = 0; i < 1000; i++)
cache.Add(string.Format("key{0}", i), string.Format("string {0}", i));
try
{
// Create invocation grid:
InvocationGridBuilder igBuilder = new InvocationGridBuilder(_gridName);
// Add dependency for the type(s) used during the invocation
igBuilder.AddDependency(typeof(EvalAndMergeMethods)); // (alternatively, you can pass in the result of Assembly.GetExecutingAssembly())
// Configure how long the InvocationGrid can remain loaded and idle after the application exits
igBuilder.LingerTime = TimeSpan.FromSeconds(60);
// The Load() method ensures that the worker processes corresponding to this invocation grid are loaded
// and that the grid's dependencies are available on all hosts.
InvocationGrid grid = igBuilder.Load();
// Associate the invocation grid with the named cache instance:
cache.InvocationGrid = grid;
string result = cache.Invoke<string, bool, string>(null, true, EvalAndMergeMethods.Eval, EvalAndMergeMethods.Merge, TimeSpan.FromMinutes(1));
Console.WriteLine("PMI call's result: {0}", result);
// This call would immediately shut down the IG and its worker processes running on the SOSS hosts:
// grid.Unload();
}
catch (StateServerException sse)
{
Console.WriteLine("Exception occurred: " + sse.Message);
}
}
} // Program
public class EvalAndMergeMethods
{
/// <summary>
/// An "Eval" method that is invoked by ScaleOut's Parallel Method Invocation (PMI) engine to evaluate
/// an object in the in-memory datagrid. A NamedCache.Invoke() call can cause this method to be invoked in
/// parallel across the farm for every object in the datagrid (if no filtering has been applied).
/// </summary>
/// <remarks>
/// Since we are using an InvocationGrid to perform this PMI operation, the SOSS service will automatically
/// deploy this code to all hosts in the ScaleOut farm and run this logic in a soss_ig_wkr.exe process.
/// </remarks>
/// <param name="strObj">A string object that has been stored in the distributed datagrid.</param>
/// <param name="bCapitalized">A PMI "parameter object" that was passed into the NamedCache.Invoke() call, allowing the parameter to be
/// applied to all objects in the cache. In this case, it indicates whether a string object's value needs to be capitalized.</param>
/// <returns>String value, conditionally capitalized</returns>
public static string Eval(string strObj, bool bCapitalized)
{
return (bCapitalized) ? strObj.ToUpper() : strObj;
}
/// <summary>
/// A "Merge" method that is invoked by ScaleOut's Parallel Method Invocation (PMI) engine to combine
/// results from a distributed operation. In this case, we're just concatinating two strings that were
/// returned by 2 different Eval method calls.
/// </summary>
/// <param name="strArg1">First string value</param>
/// <param name="strArg2">Second string value</param>
/// <returns>Single string with two args separated by a hyphen.</returns>
public static string Merge(string strArg1, string strArg2)
{
return string.Format("{0} - {1}", strArg1, strArg2);
}
}
}