Hi Galder,
thanks for your input. See my comments below:
-------- Original-Nachricht --------
Datum: Mon, 4 Apr 2011 10:09:39 +0200
Von: "Galder ZamarreƱo" <galder(a)redhat.com>
Hmmmm, the initial step in writeToKey() is to create an map entry for the
metadata, so the internal writeToKey() could indeed create a
PutLargeObjectMetadataCommand and pass that down the interceptor stack, or more simply
have a ChunkingInterceptor that implements visitPutKeyValue...() that would
keep an eye for a transaction call that puts an LargeObjectMetadata, and at
that point, the interceptor could return a new specialised
outputstream...etc. The first suggestion would be more useful if you expect other normal
cache commands such as get...etc to deal with large object related cache
calls in a different way, but I don't think that's the case here since all the
interaction would be via the Output/Input stream.
Just to make sure that we are on the same page: the supposed call sequence would appear to
be
1. User calls OutputStream writeToKey(K key)
2. writeToKey creates a PutKeyValueCommand, marking it as pertaining to a large object.
3. writeToKey passes that command down the interceptor chain.
4. A LargeObjectChunkingInterceptor or maybe LargeObjectMetadataInterceptor processes that
command, recognizing it as pertaining to a large object and thus storing a mapping from
large object key to an initially empty large object metadata instance.
5. That interceptor returns a specialized output stream.
6. User writes bytes to that output stream until chunk limit is reached.
7. Output stream calls cache.put(key, byte[]) or alternatively creates PutKeyValueCommand
itself, passing it down the interceptor chain.
8. LargeObjectChunking/MetadataInterceptor recognizes that it is dealing with a large
object and that there already exists a mapping for that key in the metadata cache.
9. Interceptor generates new chunk key.
10. Interceptor replaces key with new cunk key and calls the next interceptor.
11. Interceptor restores original key (if only consistency reasons).
12. Repeat 6 - 11 until user closes output stream.
Makes sense. Thanks.
Yeah, this information would be stored in an internal cache.
There're
several examples of such caches such as the topology cache for Hot Rod servers.
When the server is started, it creates a configuration for this type of
cache (i.e. REPL_SYNC....) and then it's named in a particular way...etc.
Found some example code in the meantime. It's obviously no rocket science.
> 3. The design suggests to use a fresh UUID as the key for each
new
> chunk. While this in all likelihood gives us a unique new key for each
> chunk I currently fail to see how that guarantees that this key maps to
> a node that is different from all the nodes already used to store chunks
> of the same Large Object. But then again I know next to nothing about
> Infinispan's constant hashing algorithm.
I think there's a service that will generate a key mapped to particular
node, so that might be a better option here to avoid all chunks going to the
same node. I think Mircea might be able to help further with this.
Implemented a workaround in the meantime. Would be fab if such a service existed.
Haven't found it yet.
>
> 4. Finally, the problem regarding eager locking and transactions
> mentioned in Manik's comment seems rather ... hairy. If we indeed forego
> transactions readers of a key just being written shouldn't be affected
> provided we write the LargeObjectMetadata object only after all chunks
> have been written. But what about writers?
Hmmmmm, I don't understand your question.
Well, the problem with transactions in this context seems to be that a transaction
*always* holds it entire associated state. In our situation this would potentially blow up
the heap.
Reading might not be a problem since in my original design a reader would not find a
mapping for a key as long as the writer has not finished writing. It would assume that the
large object it is looking for does not exist. In the updated design suggested above I
currently think about marking the metadata as being incomplete. A reader could then either
block until the writer is finished, or it could inform the reader about it.
I haven't thought deeply about the implications for concurrent writes, though. Is it
possible to lock keys outside of a transactional context? If so, this might be a solution
for reading and writing.
Cheers,
Olaf
>
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/infinispan-dev
--
Galder ZamarreƱo
Sr. Software Engineer
Infinispan, JBoss Cache
_______________________________________________
infinispan-dev mailing list
infinispan-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/infinispan-dev
--
Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
belohnen Sie mit bis zu 50,- Euro!
https://freundschaftswerbung.gmx.de