chitralverma opened a new issue, #7887:
URL: https://github.com/apache/opendal/issues/7887
### Summary
`Duration`-typed config fields cannot be set from the string config map. Any
attempt to set one (via `Operator::via_iter`, `from_uri`, or a `Configurator`
built from a key/value map) fails with `invalid type: string, expected struct
Duration`. This is a core issue and is binding-agnostic — every binding
routes
config through the same `ConfigDeserializer`.
### Root cause
Config fields are declared as plain `std::time::Duration` with the default
serde derive and no string-parsing attribute:
```rust
// core/services/redis/src/config.rs:62
pub default_ttl: Option<Duration>,
```
`serde`'s default `Duration` impl only deserializes from a `{ secs, nanos }`
struct. But `ConfigDeserializer` (core/core/src/raw/serde_util.rs) forwards
`struct` to `deserialize_any`, which hands back the raw string. So a string
value never matches the expected struct and deserialization fails.
There is no `#[serde(with = "humantime_serde")]` (or equivalent), and
`humantime` is not a dependency of these crates. The Python getter/docstring
that mention a "humantime string" are therefore misleading — no such parsing
happens.
### Affected fields
All `Duration`-typed config fields:
- `core/services/redis/src/config.rs:62` — `default_ttl`
- `core/services/memcached/src/config.rs:47` — `default_ttl`
- `core/services/cloudflare-kv/src/config.rs:37` — `default_ttl`
More broadly, **any** config field typed `Duration` hits this. Services that
need a duration currently work around it with a plain integer (e.g. S3's
`assume_role_duration_seconds: Option<u32>`), so `Duration` is effectively a
trap for any future config field.
### Steps to reproduce (core, Rust)
```rust
use std::collections::HashMap;
use opendal::Operator;
let mut opts = HashMap::new();
opts.insert("endpoint".into(), "tcp://127.0.0.1:6379".into());
opts.insert("db".into(), "0".into());
opts.insert("default_ttl".into(), "5s".into()); // any string fails
// Err: ConfigInvalid "failed to deserialize config",
// source: invalid type: string "5s", expected struct Duration
let _ = Operator::via_iter("redis", opts).unwrap();
```
The same failure occurs for `"5"`, `"100ms"`, `"0"`, etc. Only omitting the
field works. It reproduces identically from any binding (e.g. Python
`Operator("redis", default_ttl="5s")` or
`Operator.from_config(RedisConfig(..., default_ttl="5s"))`).
### Suggested fix
Add a string deserializer for `Duration` config fields in core, e.g.
`#[serde(with = "humantime_serde")]` (plus the `humantime`/`humantime-serde`
dependency), so values like `"5s"`, `"100ms"`, `"1m"` parse. This fixes every
binding at once. Bindings can then decide how to type the field (a humantime
string, and optionally a native duration type).
Note: a bare number like `"5"` (no unit) is not accepted by humantime and
should remain an error; only explicit-unit strings should be supported.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]