All Downloads are FREE. Search and download functionalities are using the official Maven repository.

groovyx.gpars.serial.SerialHandle Maven / Gradle / Ivy

Go to download

The Groovy and Java high-level concurrency library offering actors, dataflow, CSP, agents, parallel collections, fork/join and more

The newest version!
// GPars - Groovy Parallel Systems
//
// Copyright © 2008-2010, 2013  The original author or authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package groovyx.gpars.serial;

import groovyx.gpars.remote.RemoteConnection;
import groovyx.gpars.remote.RemoteHost;
import org.codehaus.groovy.util.ManagedReference;
import org.codehaus.groovy.util.ReferenceBundle;
import org.codehaus.groovy.util.ReferenceManager;
import org.codehaus.groovy.util.ReferenceType;

import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

/**
 * Weak reference to object, which was serialized to remote hosts.
 * Also keep ids of all hosts, where the object was serialized.
 * 

* While subscribed by remote nodes it keeps object alive by holding strong reference (anchor) to it *

* * @author Alex Tkachman */ public class SerialHandle extends ManagedReference { private static final ReferenceQueue queue = new ReferenceQueue(); private static final ReferenceManager manager = ReferenceManager.createThreadedManager(queue); private static final ReferenceBundle bundle = new ReferenceBundle(manager, ReferenceType.WEAK); /** * serial id of the object */ protected final UUID serialId; /** * local host */ protected final SerialContext context; /** * remote hosts subscribed to this objects */ private volatile Object subscribers; @SuppressWarnings("unused") private volatile WithSerialId anchor; // TODO: Eclipse requires this to be tagged as unused. /** * Construct handle for object with given id to it * * @param value The value to associate with the id * @param id The id, if null a new id will be generated */ private SerialHandle(final WithSerialId value, final UUID id) { super(bundle, value); context = SerialContext.get(); if (id == null) { serialId = UUID.randomUUID(); } else { serialId = id; } context.add(this); } /** * Serial id of the object * * @return The serial id */ public UUID getSerialId() { return serialId; } @Override public void finalizeReference() { context.finalizeHandle(this); super.finalizeReference(); } /** * Getter for subscribers * * @return The current subscribers */ public Object getSubscribers() { return subscribers; } /** * Subscribes host as interested in the object * * @param context The subscription context to use */ @SuppressWarnings({"SynchronizedMethod"}) public synchronized void subscribe(final SerialContext context) { if (subscribers == null) { subscribers = context; } else { if (subscribers instanceof SerialContext) { if (subscribers != context) { final Collection list = new ArrayList(2); list.add((SerialContext) subscribers); list.add(context); subscribers = list; } } else { @SuppressWarnings({"unchecked"}) final Collection list = (Collection) subscribers; for (final SerialContext remoteHost : list) { if (remoteHost == context) { return; } } list.add(context); } } anchor = get(); } @SuppressWarnings({"SynchronizedMethod"}) public synchronized void unsubscribe(final SerialContext context) { if (subscribers != null) { if (subscribers instanceof SerialContext) { if (subscribers == context) { subscribers = null; } } else { @SuppressWarnings({"unchecked"}) final List list = (List) subscribers; list.remove(context); if (list.size() == 1) { subscribers = list.get(0); } } } if (subscribers == null) { anchor = null; } } public static SerialHandle create(final WithSerialId obj, final UUID id) { if (id == null) { return new LocalSerialHandle(obj, UUID.randomUUID()); } else { return new RemoteSerialHandle(obj, id); } } private static class LocalSerialHandle extends SerialHandle { private LocalSerialHandle(final WithSerialId obj, final UUID uuid) { super(obj, uuid); } } private static class RemoteSerialHandle extends SerialHandle { private RemoteSerialHandle(final WithSerialId obj, final UUID uuid) { super(obj, uuid); } @Override public void finalizeReference() { super.finalizeReference(); context.write(new ReleaseHandle(serialId)); } public static class ReleaseHandle extends SerialMsg { private static final long serialVersionUID = -951052191389868427L; private final UUID serialId; public ReleaseHandle(final UUID serialId) { this.serialId = serialId; } @Override public void execute(final RemoteConnection conn) { final RemoteHost remoteHost = conn.getHost(); final SerialHandle handle = remoteHost.get(serialId); if (handle instanceof LocalSerialHandle) { handle.unsubscribe(remoteHost); } } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy