infinispan embedded cache with two process same machine - caching

I am new to infinispan and I am trying to start from very basic.After going through the documentation about embedded cache that lives in the same JVM process as the running program, I am trying to see how it works.
Here is my code.
public class CacheClient {
public static void main(String[] args) {
CacheClient cc = new CacheClient();
cc.start();
}
public void start() {
boolean run = true;
EmbeddedCacheManager manager = **createCacheManagerProgrammatically**();
manager.start();
Cache<Object, Object> cache = manager.getCache("dist");
Scanner sc = new Scanner(System.in);
while (run) {
System.out.println("Enter the command:");
String command = sc.next();
switch (command) {
case "add":
System.out.println("Enter the key:");
int i = sc.nextInt();
cache.put(Integer.valueOf(i), Integer.valueOf(i));
break;
case "list":
System.out.println("The keys:");
Set<Object> keySet = cache.keySet();
Iterator<Object> iter = keySet.iterator();
while (iter.hasNext()) {
System.out.println((Integer) iter.next());
}
break;
default:
run = false;
break;
}
}
sc.close();
manager.stop();
}
private EmbeddedCacheManager **createCacheManagerProgrammatically**() {
System.out
.println("Starting a cache manager with a programmatic configuration");
EmbeddedCacheManager cacheManager = new DefaultCacheManager(
GlobalConfigurationBuilder
.defaultClusteredBuilder()
.transport()
.defaultTransport()
.clusterName("dist_cluster")
.addProperty("configurationFile",
"jgroups.xml")
.build(), new ConfigurationBuilder().clustering()
.cacheMode(CacheMode.REPL_SYNC).build());
cacheManager.defineConfiguration("dist", new ConfigurationBuilder()
.clustering().cacheMode(CacheMode.REPL_SYNC).hash()
.numOwners(2).build());
return cacheManager;
}
}
From the above code my expectation is that suppose I run this program first and start adding integers to cache using add command, then when I run the same program again (another process) then the moment I use the list command, I should see the contents immediately. But I am not able to see any content when I use list in the 2nd process.
1) Is this how Embedded cache supposed to work? Is my expectation correct? If so, then what am I missing?
Please correct my mistakes and point me to a tutorial that explains clearly how it works. I tried to go through the tutorial from Infinispan documentation. But I think it's not very clear there.
Any help is highly appreciated.

I finally figured out. Please set
System.setProperty("java.net.preferIPv4Stack", "true");
and the above code will work.

Related

apache ignite destroycache socket-timeout or very slow

download the example here:https://github.com/apache/ignite/tree/master/modules/platforms/dotnet/examples
Adjust the code in ServerNode.Program.cs
namespace Apache.Ignite.Examples.ServerNode
{
public static class Program
{
public static void Main()
{
using (var ignite = Ignition.Start(Utils.GetServerNodeConfiguration()))
{
ignite.GetCluster().SetActive(true); **//add one line code here**
Utils.DeployDefaultServices(ignite);
.....
}
}
}
}
Adjust the code in Util.cs
public static IgniteConfiguration GetServerNodeConfiguration()
{
return new IgniteConfiguration
{
Localhost = "127.0.0.1",
.......
PeerAssemblyLoadingMode = PeerAssemblyLoadingMode.CurrentAppDomain,
**//add some code here to enable persistence**
DataStorageConfiguration = new DataStorageConfiguration
{
DefaultDataRegionConfiguration = new DataRegionConfiguration
{
Name = "Default_Region",
PersistenceEnabled = true
}
}
};
}
Add the destroycache method into Apache.Ignite.Examples.Thin.Sql.LinqThin.Program Main method like this:
public static void Main()
{
using (var ignite = Ignition.StartClient(Utils.GetThinClientConfiguration()))
{
Console.WriteLine();
Console.WriteLine(">>> Cache LINQ example started.");
........
var sw = Stopwatch.StartNew();
ignite.DestroyCache(OrganizationCacheName);
sw.Stop();
Console.WriteLine($"DESTROY COST {sw.ElapsedMilliseconds}");
.....
}
....
}
When execute the detroyCache method, it throws socket timeout exception sometimes, or it cost long time sometimes if destroy successfully.
But all is OK when destroyCache if donot enable persistence.
Creating and destroying caches can be slower with persistence, especially on HDD (as opposed to SSD).
You can increase socket timeout like this:
var cfg = new IgniteClientConfiguration
{
...
SocketTimeout = TimeSpan.FromSeconds(15)
};
That being said, I've tried the steps above and it prints DESTROY COST 140 on my machine (Core i7-9700, SSD).

Implement `Process.waitFor(long timeout, TimeUnit unit)` in Java 6

I am working on a legacy (Java 6/7) project that uses ProcessBuilder to request a UUID from the machine in an OS-agnostic way. I would like to use the Process.waitFor(long timeout, TimeUnit unit) method from Java 8, but this isn't implemented in Java 6. Instead, I can use waitFor(), which blocks until completion or an error.
I would like to avoid upgrading the version of Java used to 8 if possible as this necessitates a lot of other changes (migrating code away from removed internal APIs and upgrading a production Tomcat server, for example).
How can I best implement the code for executing the process, with a timeout? I was thinking of somehow implementing a schedule that checks if the process is still running and cancelling/destroying it if it is and the timeout has been reached.
My current (Java 8) code looks like this:
/** USE WMIC on Windows */
private static String getSystemProductUUID() {
String uuid = null;
String line;
List<String> cmd = new ArrayList<String>() {{
add("WMIC.exe"); add("csproduct"); add("get"); add("UUID");
}};
BufferedReader br = null;
Process p = null;
SimpleLogger.debug("Attempting to retrieve Windows System UUID through WMIC ...");
try {
ProcessBuilder pb = new ProcessBuilder().directory(getExecDir());
p = pb.command(cmd).start();
if (!p.waitFor(TIMEOUT, SECONDS)) { // No timeout in Java 6
throw new IOException("Timeout reached while waiting for UUID from WMIC!");
}
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = br.readLine()) != null) {
if (null != line) {
line = line.replace("\t", "").replace(" ", "");
if (!line.isEmpty() && !line.equalsIgnoreCase("UUID")) {
uuid = line.replace("-", "");
}
}
}
} catch (IOException | InterruptedException ex) {
uuid = null;
SimpleLogger.error(
"Failed to retrieve machine UUID from WMIC!" + SimpleLogger.getPrependedStackTrace(ex)
);
// ex.printStackTrace(System.err);
} finally {
if (null != br) {
try {
br.close();
} catch (IOException ex) {
SimpleLogger.warn(
"Failed to close buffered reader while retrieving machine UUID!"
);
}
if (null != p) {
p.destroy();
}
}
}
return uuid;
}
You can use the following code which only uses features available under Java 6:
public static boolean waitFor(Process p, long t, TimeUnit u) {
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
final AtomicReference<Thread> me = new AtomicReference<Thread>(Thread.currentThread());
ScheduledFuture<?> f = ses.schedule(new Runnable() {
#Override public void run() {
Thread t = me.getAndSet(null);
if(t != null) {
t.interrupt();
me.set(t);
}
}
}, t, u);
try {
p.waitFor();
return true;
}
catch(InterruptedException ex) {
return false;
}
finally {
f.cancel(true);
ses.shutdown();
// ensure that the caller doesn't get a spurious interrupt in case of bad timing
while(!me.compareAndSet(Thread.currentThread(), null)) Thread.yield();
Thread.interrupted();
}
}
Note that unlike other solutions you can find somewhere, this will perform the Process.waitFor() call within the caller’s thread, which is what you would expect when looking at the application with a monitoring tool. It also helps the performance for short running sub-processes, as the caller thread will not do much more than the Process.waitFor(), i.e. does not need to wait for the completion of background threads. Instead, what will happen in the background thead, is the interruption of the initiating thread if the timeout elapsed.

Prove OrganizationServiceProxy is not Thread Safe

I want to prove that re-using instances of OrganizationServiceProxy between threads will cause problems.
This console app does not have a problem re-using the same instance of OrganizationServiceProxy between threads:
class Program
{
private static OrganizationServiceProxy Service { get; set; }
static void Main(string[] args)
{
Connect(); // Initializes Service
for (int i = 0; i < 100; i++)
{
int index = i;
Task.Run(() =>
{
for (int i2 = 0; i2 < 10; i2++)
{
try
{
Console.WriteLine("Creating" + index);
Entity record = new Entity("account");
record.Id = new Guid("4986e130-45f7-e411-9454-00155d91de01");
record["name"] = index + " - " + i2;
Service.Update(record);
Console.WriteLine("Created" + index);
}
catch (Exception e)
{ }
}
});
}
Console.ReadLine(); // the name of the record ends up as 99 - 9, which is right
}
/* Initialize Service */
private static bool Connect()
{
try
{
ClientCredentials cred = new ClientCredentials();
cred.UserName.UserName = #"r";
cred.UserName.Password = #"";
IServiceManagement<IOrganizationService> serviceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(#"/XRMServices/2011/Organization.svc"));
Service = new OrganizationServiceProxy(serviceManagement, cred);
var who = new Microsoft.Crm.Sdk.Messages.WhoAmIRequest(); // used to test the connection
var whoResponse = (Microsoft.Crm.Sdk.Messages.WhoAmIResponse)Service.Execute(who); // this fails if not connected
}
catch (Exception e)
{
Console.WriteLine("Connecting to CRM.\n" + e.Message + ((e.InnerException != null) ? "\n" + e.InnerException.Message : ""));
return false;
}
return true;
}
}
The SDK states that any instance members of OrganizationServiceProxy are not guaranteed to be thread safe.
How can I cause a problem with an OrganizationServiceProxy shared between threads?
What kinds of problem are to be expected?
I'm not sure I know the specific answer to your question, but something that is marked as not guaranteed of being thread-safe just means exactly that: It may be safe, but the author has not tested for it or specifically written any thread-safe code for those classes, and thus cannot guarantee thread safety.
I do know that thread-safety definitely comes into play with Plugins on the server. This is why you are not supposed to use local fields in a Plugin class. The Plugin engine re-uses the instances of your Plugin class instead of re-instantiating them for each execution. This means it is possible that your Plugin could execute with "old data" in those local fields that was used by the last thread, which could obviously cause all kinds of problems.

Generating a proxy via Reflection.Emit only works when started with Debugging

A task at university was to implement a simple proxy generator / interceptor mechanism using Reflection.Emit.
I came up with the following program.
It seems to work just fine inside Visual Studio in debug mode [F5] (Debug -> Start Debugging) but crashes most of the time when started without debugging [Ctrl + F5] (Debug -> Start Without Debugging).
What is the difference between these two modes? (I do not refer to Debug <> Release mode).
The issue occurs on multiple machines/setups (Win XP SP3 32bit and 64bit, Windows 7 32bit).
Click for pastebin.
// The proxy generator; I assume that the error is buried along the lines emitting the IL code
public static class ProxyGenerator
{
public static T Create<T>(object obj, IInterception interception)
{
Type type = obj.GetType();
TypeBuilder proxy = DefineProxy(type);
FieldBuilder wrappedField = DefinePrivateField(proxy, "wrappedObject", type);
FieldBuilder interceptionField = DefinePrivateField(proxy, "interception", interception.GetType());
DefineConstructor(proxy, wrappedField, interceptionField);
DefineInterfaceMethods(type, proxy, wrappedField, interceptionField);
return (T) Activator.CreateInstance(proxy.CreateType(), obj, interception);
}
private static TypeBuilder DefineProxy(Type type)
{
var assemblyName = new AssemblyName {Name = "GeneratedProxyAssembly"};
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("GeneratedProxyModule");
return moduleBuilder.DefineType(
type.Name + "Proxy",
type.Attributes,
typeof (object),
type.GetInterfaces());
}
private static FieldBuilder DefinePrivateField(TypeBuilder typeBuilder, string fieldName, Type fieldType)
{
return typeBuilder.DefineField(fieldName, fieldType, FieldAttributes.Private);
}
private static void DefineConstructor(TypeBuilder typeBuilder, params FieldBuilder[] parameters)
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public, CallingConventions.Standard, parameters.Select(f => f.FieldType).ToArray());
// Emit constructor
ILGenerator g = ctor.GetILGenerator();
// Load "this" pointer and call base constructor
g.Emit(OpCodes.Ldarg_0);
g.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[0]));
// Store parameters in private fields
for (int i = 0; i < parameters.Length; i++)
{
// Load "this" pointer and parameter and store paramater in private field
g.Emit(OpCodes.Ldarg_0);
g.Emit(OpCodes.Ldarg, i + 1);
g.Emit(OpCodes.Stfld, parameters[i]);
}
// Return
g.Emit(OpCodes.Ret);
}
private static void DefineInterfaceMethods(Type type, TypeBuilder proxy, FieldInfo wrappedField, FieldInfo interceptionField)
{
// Loop through all interface methods
foreach (MethodInfo interfaceMethod in type.GetInterfaces().SelectMany(i => i.GetMethods()))
{
MethodInfo method = type.GetMethod(interfaceMethod.Name);
MethodBuilder methodBuilder = proxy.DefineMethod(
method.Name,
method.Attributes,
method.ReturnType,
method.GetParameters().Select(p => p.ParameterType).ToArray());
// Emit method
ILGenerator g = methodBuilder.GetILGenerator();
// Intercept before
EmitMethodCallOnMember(g, interceptionField, "Before", false);
// Delegate method call
EmitMethodCallOnMember(g, wrappedField, method.Name, true);
// Intercept after
EmitMethodCallOnMember(g, interceptionField, "After", false);
// Return
g.Emit(OpCodes.Ret);
}
}
private static void EmitMethodCallOnMember(ILGenerator g, FieldInfo field, string methodName, bool delegateParameters)
{
// Load "this" pointer to get address of field
g.Emit(OpCodes.Ldarg_0);
g.Emit(OpCodes.Ldflda, field);
MethodInfo method = field.FieldType.GetMethod(methodName);
if (delegateParameters)
{
// Load method parameters
for (int i = 0; i < method.GetParameters().Length; i++)
{
g.Emit(OpCodes.Ldarg, i + 1);
}
}
// Emit call
g.Emit(OpCodes.Call, method);
}
}
// Some infrastructure
public interface IInterception
{
void Before();
void After();
}
public class LogInterception : IInterception
{
public void Before()
{
Console.WriteLine("Before ... ");
}
public void After()
{
Console.WriteLine("... After");
}
}
public interface ITest
{
string DoSomething(string s1, string s2);
}
public class Test : ITest
{
public string DoSomething(string s1, string s2)
{
Console.WriteLine("... doing something ...");
return s1 + s2;
}
}
// The test program, expected output is down below
internal class Program
{
internal static void Main(string[] args)
{
var test = new Test();
var proxy = ProxyGenerator.Create<ITest>(test, new LogInterception());
Console.WriteLine(test.DoSomething("Hello", " World"));
Console.WriteLine("----------------------------------------");
Console.WriteLine(proxy.DoSomething("Hello", " World"));
Console.ReadKey();
}
}
Another question: What's the best way to narrow down such issues?
I tried to save the generated assembly to disk and open the resulting dll in Reflector but it appeared to be empty.
As mentioned above, when started in debug mode the program seems to work and prints the following output.
... doing something ...
Hello World
----------------------------------------
Before ...
... doing something ...
... After
Hello World
Thanks for your time.
Try to explicitly set x86 mode on project settings tab.
I got the fatal exception only when run program in x64 or AnyCpu mode.
Ah, I've got it. Replace Ldflda with Ldfld. It works fine even without debugger (I just ran .exe).
Ldflda is for fields you pass into method as parameters with ref or out keyword.

EC2 Java SDK - User data script

I'm looking for a way to attach a user data script to an EC2 RunRequest in the Java SDK (the equivalent of ec2-run-instances ami-1234567 -f startup-script.zip for the command line tool).
Several things I've read indicate that anything user data string with "#! " will execute, but this doesn't seem to be the case.
Is this even possible?
FYI: here's my test class:
public class AWSTest {
public static void main(String[] args) {
AWSCredentials credentials = new BasicAWSCredentials("access-key","secret-access-key");
AmazonEC2Client ec2 = new AmazonEC2Client(credentials);
RunInstancesRequest request = new RunInstancesRequest();
request.setInstanceType(InstanceType.M1Small.toString());
request.setMinCount(1);
request.setMaxCount(1);
request.setImageId("ami-84db39ed");
request.setKeyName("linux-keypair");
request.setUserData(getUserDataScript());
ec2.runInstances(request);
}
private static String getUserDataScript(){
ArrayList<String> lines = new ArrayList<String>();
lines.add("#! /bin/bash");
lines.add("curl http://www.google.com > google.html");
lines.add("shutdown -h 0");
String str = new String(Base64.encodeBase64(join(lines, "\n").getBytes()));
return str;
}
static String join(Collection<String> s, String delimiter) {
StringBuilder builder = new StringBuilder();
Iterator<String> iter = s.iterator();
while (iter.hasNext()) {
builder.append(iter.next());
if (!iter.hasNext()) {
break;
}
builder.append(delimiter);
}
return builder.toString();
}
}
Unfortunately, after I run this, I'm able to SSH into the box, and confirm that
It hasn't shut down and
It didn't download the file
Any assistance is greatly appreciated.
Best,
Zach
This works to insert user data in an instance run request, in this case specifically to join an ECS cluster:
private static String getECSuserData(String clusterName) {
String userData = "";
userData = userData + "#!/bin/bash" + "\n";
userData = userData + "echo ECS_CLUSTER=" + clusterName + " ";
userData = userData + ">> /etc/ecs/ecs.config";
String base64UserData = null;
try {
base64UserData = new String( Base64.encodeBase64( userData.getBytes( "UTF-8" )), "UTF-8" );
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return base64UserData;
}
It could be possible that the AMI your using does not support user-data script?
Please use the AMI's found at www.alestic.com.
A good reference also http://alestic.com/2009/06/ec2-user-data-scripts

Resources