From 846fa0aede9d2d3dbf894ee6b75a8870358b32d6 Mon Sep 17 00:00:00 2001 From: Igor Malinovskiy Date: Mon, 28 Oct 2024 15:07:43 +0100 Subject: [PATCH] Mkdocs unify docs (#3999) * basic mkdocs setup and workflow * rename workflow * copy lettuce * add index * integrate current wiki and docs content * integrate current wiki and docs content * add a few more links * fix branch in actions * remove redundant getting started and maven docs * Revert jedis-maven doc deletion * Exclude Dockerfile and css from spellcheck * Fix spelling * Remove assets from spellcheck-settings.yml * Add build for dev branch * Another attempt to fix spellcheck * Add some words to wordlist * Add more words to wordlist * Update .github/workflows/docs.yml Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> --------- Co-authored-by: Josh Rotenberg Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> --- .github/spellcheck-settings.yml | 3 +- .github/wordlist.txt | 12 +++ .github/workflows/docs.yml | 36 +++++++ docs/Dockerfile | 3 + docs/README.md | 15 +++ docs/advanced-usage.md | 135 +++++++++++++++++++++++++++ docs/assets/images/favicon-16x16.png | Bin 0 -> 381 bytes docs/assets/images/logo.png | Bin 0 -> 44301 bytes docs/css/extra.css | 4 + docs/faq.md | 44 +++++++++ docs/index.md | 1 + mkdocs.yml | 35 +++++++ 12 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/Dockerfile create mode 100644 docs/README.md create mode 100644 docs/advanced-usage.md create mode 100644 docs/assets/images/favicon-16x16.png create mode 100644 docs/assets/images/logo.png create mode 100644 docs/css/extra.css create mode 100644 docs/faq.md create mode 100644 docs/index.md create mode 100644 mkdocs.yml diff --git a/.github/spellcheck-settings.yml b/.github/spellcheck-settings.yml index 07b400f063..51f9d85e5d 100644 --- a/.github/spellcheck-settings.yml +++ b/.github/spellcheck-settings.yml @@ -25,4 +25,5 @@ matrix: - img sources: - '*.md' - - 'docs/**' + - 'docs/*.md' + diff --git a/.github/wordlist.txt b/.github/wordlist.txt index d60e297814..ee74a49a51 100644 --- a/.github/wordlist.txt +++ b/.github/wordlist.txt @@ -1,6 +1,7 @@ !!!Spelling check failed!!! APM ARGV +BaseObjectPoolConfig BFCommands BitOP BitPosParams @@ -16,6 +17,7 @@ ClusterPipeline ClusterPubSub ConnectionPool CoreCommands +Dockerfile EVAL EVALSHA Failback @@ -46,6 +48,7 @@ JedisCluster JedisConnectionException JedisPool JedisPooled +JedisPubSub JedisShardInfo ListPosition Ludovico @@ -174,6 +177,7 @@ incr incrBy incrByFloat ini +io json keyslot keyspace @@ -198,6 +202,9 @@ mget microservice microservices millisecondsTimestamp +MkDocs +mkdocs +md mset msetnx multikey @@ -224,6 +231,7 @@ pubsub punsubscribe py pypi +PoolConfig quickstart readonly readwrite @@ -234,10 +242,12 @@ reinitialization renamenx replicaof repo +README rpush rpushx runtime sadd +SafeEncoder scard scoreMembers sdiffstore @@ -260,6 +270,7 @@ strlen stunnel subcommands sunionstore +pipelining thevalueofmykey timeseries toctree @@ -311,3 +322,4 @@ zrevrangeByScore zrevrangeByScoreWithScores zrevrangeWithScores zunionstore +yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000000..5791f3712f --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,36 @@ +name: Publish Docs +on: + push: + branches: ["master"] +permissions: + contents: read + pages: write + id-token: write +concurrency: + group: "pages" + cancel-in-progress: false +jobs: + build-and-deploy: + concurrency: ci-${{ github.ref }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: 3.9 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mkdocs mkdocs-material pymdown-extensions mkdocs-macros-plugin + - name: Build docs + run: | + mkdocs build -d docsbuild + - name: Setup Pages + uses: actions/configure-pages@v3 + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: 'docsbuild' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 \ No newline at end of file diff --git a/docs/Dockerfile b/docs/Dockerfile new file mode 100644 index 0000000000..7fc23ffd3d --- /dev/null +++ b/docs/Dockerfile @@ -0,0 +1,3 @@ +FROM squidfunk/mkdocs-material +RUN pip install mkdocs-macros-plugin +RUN pip install mkdocs-glightbox diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..5427fa7b3d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,15 @@ +# Jedis Documentation + +This documentation uses [MkDocs](https://www.mkdocs.org/) to generate the static site. + +See [mkdocs.yml](../mkdocs.yml) for the configuration. + +To develop the documentation locally, you can use the included [Dockerfile](Dockerfile) to build a container with all the +dependencies, and run it to preview your changes: + +```bash +# in docs/ +docker build -t squidfunk/mkdocs-material . +# cd .. +docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material +``` \ No newline at end of file diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md new file mode 100644 index 0000000000..ae2f5fac5c --- /dev/null +++ b/docs/advanced-usage.md @@ -0,0 +1,135 @@ +# Advanced Usage + +## Transactions + +To do transactions in Jedis, you have to wrap operations in a transaction block, very similar to pipelining: + +```java +jedis.watch (key1, key2, ...); +Transaction t = jedis.multi(); +t.set("foo", "bar"); +t.exec(); +``` + +Note: when you have any method that returns values, you have to do like this: + + +```java +Transaction t = jedis.multi(); +t.set("fool", "bar"); +Response result1 = t.get("fool"); + +t.zadd("foo", 1, "barowitch"); t.zadd("foo", 0, "barinsky"); t.zadd("foo", 0, "barikoviev"); +Response> sose = t.zrange("foo", 0, -1); // get the entire sortedset +t.exec(); // dont forget it + +String foolbar = result1.get(); // use Response.get() to retrieve things from a Response +int soseSize = sose.get().size(); // on sose.get() you can directly call Set methods! + +// List allResults = t.exec(); // you could still get all results at once, as before +``` +Note that a Response Object does not contain the result before t.exec() is called (it is a kind of a Future). Forgetting exec gives you exceptions. In the last lines, you see how transactions/pipelines were dealt with before version 2. You can still do it that way, but then you need to extract objects from a list, which contains also Redis status messages. + +Note 2: Redis does not allow to use intermediate results of a transaction within that same transaction. This does not work: + +```java +// this does not work! Intra-transaction dependencies are not supported by Redis! +jedis.watch(...); +Transaction t = jedis.multi(); +if(t.get("key1").equals("something")) + t.set("key2", "value2"); +else + t.set("key", "value"); +``` + +However, there are some commands like setnx, that include such a conditional execution. Those are of course supported within transactions. You can build your own customized commands using EVAL / LUA scripting. + + +## Pipelining + +Sometimes you need to send a bunch of different commands. A very cool way to do that, and have better performance than doing it the naive way, is to use pipelining. This way you send commands without waiting for response, and you actually read the responses at the end, which is faster. + +Here is how to do it: + +```java +Pipeline p = jedis.pipelined(); +p.set("fool", "bar"); +p.zadd("foo", 1, "barowitch"); p.zadd("foo", 0, "barinsky"); p.zadd("foo", 0, "barikoviev"); +Response pipeString = p.get("fool"); +Response> sose = p.zrange("foo", 0, -1); +p.sync(); + +int soseSize = sose.get().size(); +Set setBack = sose.get(); +``` +For more explanations see code comments in the transaction section. + + +## Publish/Subscribe + +To subscribe to a channel in Redis, create an instance of JedisPubSub and call subscribe on the Jedis instance: + +```java +class MyListener extends JedisPubSub { + public void onMessage(String channel, String message) { + } + + public void onSubscribe(String channel, int subscribedChannels) { + } + + public void onUnsubscribe(String channel, int subscribedChannels) { + } + + public void onPSubscribe(String pattern, int subscribedChannels) { + } + + public void onPUnsubscribe(String pattern, int subscribedChannels) { + } + + public void onPMessage(String pattern, String channel, String message) { + } +} + +MyListener l = new MyListener(); + +jedis.subscribe(l, "foo"); +``` +Note that subscribe is a blocking operation because it will poll Redis for responses on the thread that calls subscribe. A single JedisPubSub instance can be used to subscribe to multiple channels. You can call subscribe or psubscribe on an existing JedisPubSub instance to change your subscriptions. + + +### Monitoring + +To use the monitor command you can do something like the following: + +```java +new Thread(new Runnable() { + public void run() { + Jedis j = new Jedis("localhost"); + for (int i = 0; i < 100; i++) { + j.incr("foobared"); + try { + Thread.sleep(200); + } catch (InterruptedException e) { + } + } + j.disconnect(); + } +}).start(); + +jedis.monitor(new JedisMonitor() { + public void onCommand(String command) { + System.out.println(command); + } +}); +``` + +## Miscellaneous + +### A note about String and Binary - what is native? + +Redis/Jedis talks a lot about Strings. And here [[http://redis.io/topics/internals]] it says Strings are the basic building block of Redis. However, this stress on strings may be misleading. Redis' "String" refer to the C char type (8 bit), which is incompatible with Java Strings (16-bit). Redis sees only 8-bit blocks of data of predefined length, so normally it doesn't interpret the data (it's "binary safe"). Therefore in Java, byte[] data is "native", whereas Strings have to be encoded before being sent, and decoded after being retrieved by the SafeEncoder. This has some minor performance impact. +In short: if you have binary data, don't encode it into String, but use the binary versions. + +### A note on Redis' master/slave distribution + +A Redis network consists of redis servers, which can be either masters or slaves. Slaves are synchronized to the master (master/slave replication). However, master and slaves look identical to a client, and slaves do accept write requests, but they will not be propagated "up-hill" and could eventually be overwritten by the master. It makes sense to route reads to slaves, and write demands to the master. Furthermore, being a slave doesn't prevent from being considered master by another slave. diff --git a/docs/assets/images/favicon-16x16.png b/docs/assets/images/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..ba4b7ac1183f6fbcf5ccd23b42a84d659e7337aa GIT binary patch literal 381 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 literal 0 HcmV?d00001 diff --git a/docs/css/extra.css b/docs/css/extra.css new file mode 100644 index 0000000000..22807a194a --- /dev/null +++ b/docs/css/extra.css @@ -0,0 +1,4 @@ +/* extra.css */ +.md-header { + background-color: #FB2A2C; +} diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 0000000000..ce021b37ce --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,44 @@ +# Frequently Asked Questions + +## If you get `java.net.SocketTimeoutException: Read timed out` exception + +Try setting own `timeout` value when constructing `JedisPool` using the following constructor: +```java +JedisPool(GenericObjectPoolConfig poolConfig, String host, int port, int timeout) +``` +where `timeout` is given as milliseconds. + +Default `timeout` value is **2 seconds**. + +## JedisPool blocks after getting 8 connections + +JedisPool defaults to 8 connections, you can change this in the PoolConfig: + +```java +JedisPoolConfig poolConfig = new JedisPoolConfig(); +poolConfig.setMaxTotal(maxTotal); // maximum active connections +poolConfig.setMaxIdle(maxIdle); // maximum idle connections +``` + +Take into account that `JedisPool` inherits commons-pool [BaseObjectPoolConfig](https://commons.apache.org/proper/commons-pool/api-2.3/org/apache/commons/pool2/impl/BaseObjectPoolConfig.html) which has a lot of configuration parameters. +We've set some defined ones which suit most of the cases. In case, you experience [issues](https://github.com/xetorthio/jedis/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+JedisPool) tuning these parameters may help. + +## How to configure the buffer size of socket(s) + +The buffer size of all Jedis sockets in an application can be configured through system property. + +Buffer size of input stream can be configured by setting `jedis.bufferSize.input` or `jedis.bufferSize` system property. +Buffer size of output stream can be configured by setting `jedis.bufferSize.output` or `jedis.bufferSize` system property. +If you want to set the buffer size of both input and output stream to same value, you can just set `jedis.bufferSize`. + +Note: This feature is available since Jedis 4.2.0. + +## How to avoid cluster initialization error + +As of Jedis 4.0.0, a `JedisClusterOperationException` is raised with the message `Could not initialize cluster slots cache.` when the cluster initialization process fails. + +Should you would want to avoid this error (for example, creating `JedisConnectionFactory` to an unavailable cluster for a spring-data-redis `Bean`), set the system property `jedis.cluster.initNoError` to any value. +In the console, add the option `-Djedis.cluster.initNoError`. +In an application, `System.setProperty("jedis.cluster.initNoError", "");` can be set before creating any cluster object. + +Note: This feature is available since Jedis 4.4.2. \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000..074a48bf84 --- /dev/null +++ b/docs/index.md @@ -0,0 +1 @@ +{% include 'README.md' %} \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000000..83000d59c1 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,35 @@ +site_name: Jedis +repo_name: Jedis +site_author: Redis, Inc. +site_description: Jedis is a Redis client for the JVM. +repo_url: https://github.com/redis/jedis +remote_branch: gh-pages + +theme: + name: material + logo: assets/images/logo.png + favicon: assets/images/favicon-16x16.png +extra_css: + - css/extra.css + +plugins: + - search + - macros: + include_dir: . + +nav: + - Home: index.md + - Migrating from older versions: + - 3 to 4: + - Breaking changes: 3to4.md + - Primitives: 3to4-primitives.md + - ZSET: 3to4-zset-list.md + - Using Jedis with ...: + - Search: redisearch.md + - JSON: redisjson.md + - Failover: failover.md + - FAQ: faq.md + - API Reference: https://www.javadoc.io/doc/redis.clients/jedis/latest/index.html + - Jedis Guide: https://redis.io/docs/latest/develop/connect/clients/java/jedis/ + - Redis Command Reference: https://redis.io/docs/latest/commands/ +