Search in sources :

Example 11 with DeleteRequest

use of org.hbase.async.DeleteRequest in project opentsdb by OpenTSDB.

the class UniqueId method deleteAsync.

/**
   * Attempts to remove the mappings for the given string from the UID table
   * as well as the cache. If used, the caller should remove the entry from all
   * TSD caches as well.
   * <p>
   * WARNING: This is a best attempt only method in that we'll lookup the UID
   * for the given string, then issue two delete requests, one for each mapping.
   * If either mapping fails then the cache can be re-populated later on with
   * stale data. In that case, please run the FSCK utility.
   * <p>
   * WARNING 2: This method will NOT delete time series data or TSMeta data 
   * associated with the UIDs. It only removes them from the UID table. Deleting
   * a metric is generally safe as you won't query over it in the future. But
   * deleting tag keys or values can cause queries to fail if they find data
   * without a corresponding name.
   * 
   * @param name The name of the UID to delete
   * @return A deferred to wait on for completion. The result will be null if
   * successful, an exception otherwise.
   * @throws NoSuchUniqueName if the UID string did not exist in storage
   * @throws IllegalStateException if the TSDB wasn't set for this UID object
   * @since 2.2
   */
public Deferred<Object> deleteAsync(final String name) {
    if (tsdb == null) {
        throw new IllegalStateException("The TSDB is null for this UID object.");
    }
    final byte[] uid = new byte[id_width];
    final ArrayList<Deferred<Object>> deferreds = new ArrayList<Deferred<Object>>(2);
    /** Catches errors and still cleans out the cache */
    class ErrCB implements Callback<Object, Exception> {

        @Override
        public Object call(final Exception ex) throws Exception {
            name_cache.remove(name);
            id_cache.remove(fromBytes(uid));
            LOG.error("Failed to delete " + fromBytes(kind) + " UID " + name + " but still cleared the cache", ex);
            return ex;
        }
    }
    /** Used to wait on the group of delete requests */
    class GroupCB implements Callback<Deferred<Object>, ArrayList<Object>> {

        @Override
        public Deferred<Object> call(final ArrayList<Object> response) throws Exception {
            name_cache.remove(name);
            id_cache.remove(fromBytes(uid));
            LOG.info("Successfully deleted " + fromBytes(kind) + " UID " + name);
            return Deferred.fromResult(null);
        }
    }
    /** Called after fetching the UID from storage */
    class LookupCB implements Callback<Deferred<Object>, byte[]> {

        @Override
        public Deferred<Object> call(final byte[] stored_uid) throws Exception {
            if (stored_uid == null) {
                return Deferred.fromError(new NoSuchUniqueName(kind(), name));
            }
            System.arraycopy(stored_uid, 0, uid, 0, id_width);
            final DeleteRequest forward = new DeleteRequest(table, toBytes(name), ID_FAMILY, kind);
            deferreds.add(tsdb.getClient().delete(forward));
            final DeleteRequest reverse = new DeleteRequest(table, uid, NAME_FAMILY, kind);
            deferreds.add(tsdb.getClient().delete(reverse));
            final DeleteRequest meta = new DeleteRequest(table, uid, NAME_FAMILY, toBytes((type.toString().toLowerCase() + "_meta")));
            deferreds.add(tsdb.getClient().delete(meta));
            return Deferred.group(deferreds).addCallbackDeferring(new GroupCB());
        }
    }
    final byte[] cached_uid = name_cache.get(name);
    if (cached_uid == null) {
        return getIdFromHBase(name).addCallbackDeferring(new LookupCB()).addErrback(new ErrCB());
    }
    System.arraycopy(cached_uid, 0, uid, 0, id_width);
    final DeleteRequest forward = new DeleteRequest(table, toBytes(name), ID_FAMILY, kind);
    deferreds.add(tsdb.getClient().delete(forward));
    final DeleteRequest reverse = new DeleteRequest(table, uid, NAME_FAMILY, kind);
    deferreds.add(tsdb.getClient().delete(reverse));
    final DeleteRequest meta = new DeleteRequest(table, uid, NAME_FAMILY, toBytes((type.toString().toLowerCase() + "_meta")));
    deferreds.add(tsdb.getClient().delete(meta));
    return Deferred.group(deferreds).addCallbackDeferring(new GroupCB()).addErrback(new ErrCB());
}
Also used : Deferred(com.stumbleupon.async.Deferred) ArrayList(java.util.ArrayList) HBaseException(org.hbase.async.HBaseException) Callback(com.stumbleupon.async.Callback) DeleteRequest(org.hbase.async.DeleteRequest)

Example 12 with DeleteRequest

use of org.hbase.async.DeleteRequest in project opentsdb by OpenTSDB.

the class UniqueId method rename.

/**
   * Reassigns the UID to a different name (non-atomic).
   * <p>
   * Whatever was the UID of {@code oldname} will be given to {@code newname}.
   * {@code oldname} will no longer be assigned a UID.
   * <p>
   * Beware that the assignment change is <b>not atommic</b>.  If two threads
   * or processes attempt to rename the same UID differently, the result is
   * unspecified and might even be inconsistent.  This API is only here for
   * administrative purposes, not for normal programmatic interactions.
   * @param oldname The old name to rename.
   * @param newname The new name.
   * @throws NoSuchUniqueName if {@code oldname} wasn't assigned.
   * @throws IllegalArgumentException if {@code newname} was already assigned.
   * @throws HBaseException if there was a problem with HBase while trying to
   * update the mapping.
   */
public void rename(final String oldname, final String newname) {
    final byte[] row = getId(oldname);
    final String row_string = fromBytes(row);
    {
        byte[] id = null;
        try {
            id = getId(newname);
        } catch (NoSuchUniqueName e) {
        // OK, we don't want the new name to be assigned.
        }
        if (id != null) {
            throw new IllegalArgumentException("When trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": new name already" + " assigned ID=" + Arrays.toString(id));
        }
    }
    if (renaming_id_names.contains(row_string) || renaming_id_names.contains(newname)) {
        throw new IllegalArgumentException("Ongoing rename on the same ID(\"" + Arrays.toString(row) + "\") or an identical new name(\"" + newname + "\")");
    }
    renaming_id_names.add(row_string);
    renaming_id_names.add(newname);
    final byte[] newnameb = toBytes(newname);
    // but the forward mapping without reverse mapping is bad.
    try {
        final PutRequest reverse_mapping = new PutRequest(table, row, NAME_FAMILY, kind, newnameb);
        hbasePutWithRetry(reverse_mapping, MAX_ATTEMPTS_PUT, INITIAL_EXP_BACKOFF_DELAY);
    } catch (HBaseException e) {
        LOG.error("When trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": Failed to update reverse" + " mapping for ID=" + Arrays.toString(row), e);
        renaming_id_names.remove(row_string);
        renaming_id_names.remove(newname);
        throw e;
    }
    // Now create the new forward mapping.
    try {
        final PutRequest forward_mapping = new PutRequest(table, newnameb, ID_FAMILY, kind, row);
        hbasePutWithRetry(forward_mapping, MAX_ATTEMPTS_PUT, INITIAL_EXP_BACKOFF_DELAY);
    } catch (HBaseException e) {
        LOG.error("When trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": Failed to create the" + " new forward mapping with ID=" + Arrays.toString(row), e);
        renaming_id_names.remove(row_string);
        renaming_id_names.remove(newname);
        throw e;
    }
    // Update cache.
    // add     new name -> ID
    addIdToCache(newname, row);
    // update  ID -> new name
    id_cache.put(fromBytes(row), newname);
    // remove  old name -> ID
    name_cache.remove(oldname);
    // Delete the old forward mapping.
    try {
        final DeleteRequest old_forward_mapping = new DeleteRequest(table, toBytes(oldname), ID_FAMILY, kind);
        client.delete(old_forward_mapping).joinUninterruptibly();
    } catch (HBaseException e) {
        LOG.error("When trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": Failed to remove the" + " old forward mapping for ID=" + Arrays.toString(row), e);
        throw e;
    } catch (Exception e) {
        final String msg = "Unexpected exception when trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": Failed to remove the" + " old forward mapping for ID=" + Arrays.toString(row);
        LOG.error("WTF?  " + msg, e);
        throw new RuntimeException(msg, e);
    } finally {
        renaming_id_names.remove(row_string);
        renaming_id_names.remove(newname);
    }
// Success!
}
Also used : PutRequest(org.hbase.async.PutRequest) HBaseException(org.hbase.async.HBaseException) DeleteRequest(org.hbase.async.DeleteRequest) HBaseException(org.hbase.async.HBaseException)

Aggregations

DeleteRequest (org.hbase.async.DeleteRequest)12 ArrayList (java.util.ArrayList)9 KeyValue (org.hbase.async.KeyValue)8 Callback (com.stumbleupon.async.Callback)7 Scanner (org.hbase.async.Scanner)7 Deferred (com.stumbleupon.async.Deferred)6 HBaseException (org.hbase.async.HBaseException)4 Map (java.util.Map)2 PutRequest (org.hbase.async.PutRequest)2 DeferredGroupException (com.stumbleupon.async.DeferredGroupException)1 DBException (com.yahoo.ycsb.DBException)1 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Set (java.util.Set)1 TreeMap (java.util.TreeMap)1 TreeSet (java.util.TreeSet)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Query (net.opentsdb.core.Query)1