Hello, Dmitriy, Igor!
Dmitriy, as you have noted, most cache API functions are parameterized
with the hash codes, and the function for creating the hash codes is
documented. I personally see no harm in using hash codes as it is
defined by low-level client operations. But it may be better to enforce
the use of cache names throughout the Python library, or use names and
hash codes interchangeably where possible.
Igor, you are right, due to the procedural nature of my client library,
there is no cache class in it. Caches in Ignite, from Python
perspective, are one-off, unique, immutable objects. The client code
will not benefit much from associating any additional context with them.
On the contrary, handling cache objects in its string or integer
representation may sometimes be advantageous.
I guess, the implied question here is: why I chose a procedural approach
first of all? Well, I am glad to answer it too, although the answer will
be more verbose.
Python is often referred as a multi-paradigm programming language, but
at heart it is a procedural scripting language. It has no obligatory
object orientation that could influence Java or C# clients' architecture.
It is also worth noting, that Python has such an elaborate and versatile
built-in types, so its classes (`object` descendants) is never meant to
be used as plain data containers. That is unlike JavaScript, where
`object` is a legitimate default complex data type. Any combination of
list/set/dict/defaultdict/OrderedDict is always a better, more Pythonic
choice; getter/setter semantics is considered an anti-pattern.
Considering the above, the client API architecture could be chosen
depending on the application field. Aiming for the most versatility,
however, I decided to implement lower-level procedural API.
“Lower-level” in this case does not mean extra efforts for the end user.
Feel free to review the rest of the examples and make sure that those
code snippets actually take less and do more, comparing to the
equivalent code using other client APIs.
If that is still not satisfying, any kind of object-oriented wrapper can
be built on top of the procedural implementation with little time and
effort. In fact, before taking the present course of actions, I
considered the following implementations of other services' clients:
- key-value libraries, like redis-py, that have their methods
incapsulated in connection class,
- RDBMS libraries like psycopg2 with their cursor classes − it could be
an architectural choice for SQL and scan queries-oriented client,
- boto3 (Amazon S3 client) have its methods incapsulated in bucket
objects, somewhat analogous to Ignite caches, but notably different: a)
S3 supports only one data type: file, b) bucket can be reconfigured on
the fly, unlike Ignite cache,
- there could be other architectural choices too.
I will be glad to answer your further questions. If you have suggestions
about higher-level abstractions and their use cases, please let me know.
Dmitry
On 07/24/2018 10:43 PM, Dmitriy Setrakyan wrote:> Yes, looks strange?
Why is the hash code part of API?
>
> On Tue, Jul 24, 2018, 13:38 Igor Sapego <isap...@apache.org> wrote:
>
>> Ok, I've quickly looked through API and I have a questions. Here
>> is the code from the example:
>>
>> cache_name = 'my cache'
>> hash_code = hashcode(cache_name)
>> cache_create(conn, cache_name)
>> result = cache_put(conn, hash_code, 'my key', 42)
>>
>> I'm not familiar with python, so here is the question. Why there is
>> no "cache" class, and functions with hash code are used?
>>
>> Best Regards,
>> Igor