protected ClientKeyBlock encode( ObjectContainer container, ClientContext context, boolean calledByCB) throws InsertException { if (persistent) { container.activate(sourceData, 1); container.activate(cb, 1); } ClientKeyBlock block; boolean shouldSend; synchronized (this) { if (finished) return null; if (sourceData == null) { Logger.error(this, "Source data is null on " + this + " but not finished!"); return null; } block = innerEncode(context.random, container); shouldSend = (resultingURI == null); resultingURI = block.getClientKey().getURI(); } if (logMINOR) Logger.minor( this, "Encoded " + resultingURI + " for " + this + " shouldSend=" + shouldSend + " dontSendEncoded=" + dontSendEncoded); if (shouldSend && !dontSendEncoded) cb.onEncode(block.getClientKey(), this, container, context); if (shouldSend && persistent) container.store(this); if (persistent && !calledByCB) container.deactivate(cb, 1); return block; }
public void schedule(ObjectContainer container, ClientContext context) throws InsertException { synchronized (this) { if (finished) { if (logMINOR) Logger.minor(this, "Finished already: " + this); return; } } if (getCHKOnly) { boolean deactivateCB = false; if (persistent) { deactivateCB = !container.ext().isActive(cb); if (deactivateCB) container.activate(cb, 1); container.activate(parent, 1); } ClientKeyBlock block = encode(container, context, true); cb.onEncode(block.getClientKey(), this, container, context); parent.completedBlock(false, container, context); cb.onSuccess(this, container, context); finished = true; if (persistent) { container.store(this); if (deactivateCB) container.deactivate(cb, 1); } } else { getScheduler(context).registerInsert(this, persistent, true, container); } }
/** * Convert a ClientKeyBlock to a Bucket. If an error occurs, report it via onFailure and return * null. */ protected Bucket extract( ClientKeyBlock block, Object token, ObjectContainer container, ClientContext context) { Bucket data; try { data = block.decode( context.getBucketFactory(persistent), (int) (Math.min(ctx.maxOutputLength, Integer.MAX_VALUE)), false); } catch (KeyDecodeException e1) { if (Logger.shouldLog(Logger.MINOR, this)) Logger.minor(this, "Decode failure: " + e1, e1); onFailure( new FetchException(FetchException.BLOCK_DECODE_ERROR, e1.getMessage()), token, container, context); return null; } catch (TooBigException e) { onFailure( new FetchException(FetchException.TOO_BIG, e.getMessage()), token, container, context); return null; } catch (IOException e) { Logger.error(this, "Could not capture data - disk full?: " + e, e); onFailure(new FetchException(FetchException.BUCKET_ERROR, e), token, container, context); return null; } if (Logger.shouldLog(Logger.MINOR, this)) Logger.minor( this, data == null ? "Could not decode: null" : ("Decoded " + data.size() + " bytes")); return data; }
public boolean send( NodeClientCore core, RequestScheduler sched, final ClientContext context, ChosenBlock req) { // Ignore keyNum, key, since we're only sending one block. ClientKeyBlock b; ClientKey key = null; if (SingleBlockInserter.logMINOR) Logger.minor(this, "Starting request: " + SingleBlockInserter.this); BlockItem block = (BlockItem) req.token; try { try { b = innerEncode( context.random, block.uri, block.copyBucket, block.isMetadata, block.compressionCodec, block.sourceLength, compressorDescriptor); } catch (CHKEncodeException e) { throw new LowLevelPutException( LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e); } catch (SSKEncodeException e) { throw new LowLevelPutException( LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e); } catch (MalformedURLException e) { throw new LowLevelPutException( LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e); } catch (InsertException e) { throw new LowLevelPutException( LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e); } catch (IOException e) { throw new LowLevelPutException( LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e); } catch (InvalidCompressionCodecException e) { throw new LowLevelPutException( LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e); } if (b == null) { Logger.error( this, "Asked to send empty block on " + SingleBlockInserter.this, new Exception("error")); return false; } key = b.getClientKey(); final ClientKey k = key; if (block.persistent) { context.jobRunner.queue( new DBJob() { public boolean run(ObjectContainer container, ClientContext context) { if (!container.ext().isStored(SingleBlockInserter.this)) return false; container.activate(SingleBlockInserter.this, 1); onEncode(k, container, context); container.deactivate(SingleBlockInserter.this, 1); return false; } }, NativeThread.NORM_PRIORITY + 1, false); } else { context.mainExecutor.execute( new Runnable() { public void run() { onEncode(k, null, context); } }, "Got URI"); } if (req.localRequestOnly) try { core.node.store(b, false, req.canWriteClientCache, true, false); } catch (KeyCollisionException e) { throw new LowLevelPutException(LowLevelPutException.COLLISION); } else core.realPut(b, req.canWriteClientCache, req.forkOnCacheable); } catch (LowLevelPutException e) { if (e.code == LowLevelPutException.COLLISION) { // Collision try { ClientSSKBlock collided = (ClientSSKBlock) core.node.fetch((ClientSSK) key, true, true, req.canWriteClientCache); byte[] data = collided.memoryDecode(true); byte[] inserting = BucketTools.toByteArray(block.copyBucket); if (collided.isMetadata() == block.isMetadata && collided.getCompressionCodec() == block.compressionCodec && Arrays.equals(data, inserting)) { if (SingleBlockInserter.logMINOR) Logger.minor(this, "Collided with identical data: " + SingleBlockInserter.this); req.onInsertSuccess(context); return true; } } catch (KeyVerifyException e1) { Logger.error(this, "Caught " + e1 + " when checking collision!", e1); } catch (KeyDecodeException e1) { Logger.error(this, "Caught " + e1 + " when checking collision!", e1); } catch (IOException e1) { Logger.error(this, "Caught " + e1 + " when checking collision!", e1); } } req.onFailure(e, context); if (SingleBlockInserter.logMINOR) Logger.minor(this, "Request failed: " + SingleBlockInserter.this + " for " + e); return true; } catch (DatabaseDisabledException e) { // Impossible, and nothing to do. Logger.error(this, "Running persistent insert but database is disabled!"); } finally { block.copyBucket.free(); } if (SingleBlockInserter.logMINOR) Logger.minor(this, "Request succeeded: " + SingleBlockInserter.this); req.onInsertSuccess(context); return true; }