Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to Send and receive multiple values with different timestamps of the same resource #1192

Closed
Michal-Wadowski opened this issue Jan 4, 2022 · 43 comments
Labels
question Any question about leshan

Comments

@Michal-Wadowski
Copy link
Contributor

It seems to be no way to Send multiple data by client from one resource with different timestamps. Also I don't see possibility to receive this kind of data by server (by SendListener).

However I can see LwM2mDecoder.decodeTimestampedData() and LwM2mEncoder.encodeTimestampedData() which implementations allow to send timestamped data.

I created POC code locally that uses already implemented decodeTimestampedData() and encodeTimestampedData(), so technically it's possible to do that, but it needs more investigation.

@Michal-Wadowski Michal-Wadowski changed the title Unable to Send and receive multiple values with different timestamps Unable to Send and receive multiple values with different timestamps of the same resource Jan 4, 2022
@Michal-Wadowski
Copy link
Contributor Author

I tried to update ReadResponse to allow send list of timestamped nodes insead of one node but it turned out it requires a lot of changes in related classes. Finally, even if I resolved conflicts (and break a lot of code) I end up on firing LwM2mEncoder.encodeTimestampedData() method with data type Map<LwM2mPath, List<TimestampedLwM2mNode>> which is not supported. There is supported only encode nodes with different timestamps but one path.

@sbernard31
Copy link
Contributor

Send timestamped value is relative to stored notification feature. (and so relative to observe)
There is an issue about this : #596. (following links you should get more details about this)
And today this is not implemented.

However I can see LwM2mDecoder.decodeTimestampedData() and LwM2mEncoder.encodeTimestampedData() which implementations allow to send timestamped data.

Yep stored notification is supported at Server side and not a client side but some part of the work was done at encoder side.
This helps to write some tests : ObserveTimeStampTest.java

About implementing stored notification feature at client this could be a bit complication as this is part of Observe feature which is not really in the spirit of CoAP Observe. (I don't know if this is doable with current Californium API)

Also I don't see possibility to receive this kind of data by server (by SendListener).

You talk about Send Operation, right ?
Reading the specification I don't understand this is allowed, I mean sending timestamped value with Send Operation. but maybe I missed something. Do you find anything about that in the specification ? 🤔

@sbernard31 sbernard31 added the question Any question about leshan label Jan 5, 2022
@Michal-Wadowski
Copy link
Contributor Author

Yes, my main purpose is to allow to Send multiple timestamped values for some path. For example device can collect some of data and send this with historical values. I'm not sure if it's allowed with specification either.

@sbernard31
Copy link
Contributor

Do you find any hint in the specification or in https://github.com/OpenMobileAlliance/OMA_LwM2M_for_Developers/issues which could make you think this is allowed ?

For now I found nothing.

There is maybe a little hint which could me think this is not allowed :
In LWM2M v1.2 a new format was added LWM2M CBOR which can be used with Send Operation and I understand there is no way to add timestamped value. See http://www.openmobilealliance.org/release/LightweightM2M/V1_2-20201110-A/HTML-Version/OMA-TS-LightweightM2M_Core-V1_2-20201110-A.html#7-4-4-0-744-LwM2M-CBOR

We can open at OMA but not sure we get an answer.

@sbernard31
Copy link
Contributor

I opened an issue at OpenMobileAlliance/OMA_LwM2M_for_Developers#538

@sbernard31
Copy link
Contributor

We get an answer from OMA.
Surprisingly to me, that sounds to be allowed.
So I guess we need to adapt the API to allow this.

We should first define API directly exposed to users like SendRequest and SendListener.

@Michal-Wadowski
Copy link
Contributor Author

Michal-Wadowski commented Jan 26, 2022

@sbernard31 What do you think, how Send with timestamp implementation should look like?

I created branch opl/send_timestamp with POC to show the easiest way to add timestamp to Send command (and incidentally Read). What do you think, it's a good way?

Another question is: is it possible to send multiple timestamped values with Send? (I mean one resource with historical values send at once). It looks much more complicated than just add timestamp to single value. I'm not sure if it's even possible within LwM2M specification.

@sbernard31
Copy link
Contributor

is it possible to send multiple timestamped values with Send? (I mean one resource with historical values send at once)

Following, OpenMobileAlliance/OMA_LwM2M_for_Developers#538 (comment), I would says it's possible. Do you understand the same thing ?

how Send with timestamp implementation should look like?
I created branch opl/send_timestamp with POC to show the easiest way to add timestamp to Send command (and incidentally Read). What do you think, it's a good way?

We already have a kind of API TimestampedLwM2mNode used for historical Notification (See ObserveResponse)
I guess we should reused it unless we discover this is not adapted. If we need a new API because this one is not adapted we should use it for historical notification too.

Concretely, at server side this should be about replace LwM2mNode by TimestampedLwM2mNode.

At client side this is clearly less easy....
Could you describe your use cases ?
Because for now I don't get why this is the enabler which add the timestamp value.
The enabler is supposed to return the current value, so it makes not so much sense to me to attach a timestamp to it, or I missed something ?

(Not directly linked but I had this new API idea #981. There is no timestamp too ...)

It looks much more complicated than just add timestamp to single value. It should be returned some kind of LwM2mMultipleResource ?

Maybe an approach could be to have a kind of DataCollector which :

  • collect data periodically
  • timestamped it at moment it collect it.
  • then send collected at a larger period ?

@sbernard31
Copy link
Contributor

I think about this again and SendRequest API use a map of path => node.
If we use TimestampedNode, using a map is no more adapted as we can have several time the same path.

So don't know how this should looks like for now 🤔 :

(@Michal-Wadowski what is the more urgent subject for you ? this or OSCORE ?)

@Michal-Wadowski
Copy link
Contributor Author

Michal-Wadowski commented Feb 3, 2022

(@Michal-Wadowski what is the more urgent subject for you ? this or OSCORE ?)

Good question :) Both are important quite equally, but I think current issue would be easier to implement than OSCORE. So maybe I'll focus on Send first 🙂

According other questions, I'm still wondering how to solve it in best way...

@sbernard31
Copy link
Contributor

Tomorrow, I will try to think about this . (Do no hesitate to share your thought)

@Michal-Wadowski
Copy link
Contributor Author

Sorry, I was busy with other tasks until now. Now I have time to work on this task.

At the beginning I will focus on the server side because it looks easier to handle.

I'm not sure if we can use TimestampedNode. Maybe it should be something like Map<Timestamp, LwM2mNode> (TimestampedLwM2mNodeList ?)

Unfortunately I don't know how to test client and server separately in integration tests. Splitting this functionality could ease implementation, but I'm not sure if it is even possible 😐. But I'll try.

@Michal-Wadowski
Copy link
Contributor Author

Unfortunately I don't know how to test client and server separately in integration tests.

Ok, I think I found solution for that 😄 Now I can develop some parts independently which is easier to do. I'll share POC soon 🙂

@sbernard31
Copy link
Contributor

Maybe, do not go deeper in the code before we agree on the API ?

Unfortunately I don't know how to test client and server separately in integration tests. Splitting this functionality could ease implementation, but I'm not sure if it is even possible neutral_face. But I'll try.

Eventually we can simulate the SendRequest from the client like with one of this way :

@Michal-Wadowski
Copy link
Contributor Author

Michal-Wadowski commented Feb 10, 2022

Maybe, do not go deeper in the code before we agree on the API ?

I agree, we should discuss about API and architecture. I just send POC as an example (one of many) how we can implement this functionality: (opl/send_timestamp).

According to separating client/server test - I'm not able to avoid activities like registration etc, but I can inject custom response even if the client is not able to do it yet. Of course it's kind of hack but it works for me (finally it's only POC).

So my proposition is to create TimestampedLwM2mNodeList (the name can be always changed) which is resource-like node that contains map timestamp->value. I'm not sure if it should implement LwM2mResource or LwM2mNode interface so I chose simpler option. Introducing TimestampedLwM2mNodeList type seems don't break current implementation.

I think the main changes should be done in LwM2mNodeSenMLDecoder so I prepared first test to cover new approach. It doesn't pass yet due to lack of implementation.

I know that #981 could bring some improvements, but I think it needs a lot of rewriting. Maybe it could be done after current functionality?

@Michal-Wadowski
Copy link
Contributor Author

I added implementation LwM2mNodeSenMLDecoder to handle TimestampedLwM2mNodeList. Now few tests are broken so I temporarily ignore them. I changed TimestampedLwM2mNodeList as LwM2mResource implementation because it looks like more suitable.

@Michal-Wadowski
Copy link
Contributor Author

I think we could merge TimestampedLwM2mNode and TimestampedLwM2mNodeList into single class. It can behave like single node with timestamp and getValue() could return first (or last) element of timestamped list and also allow to get full of history if needed.

@sbernard31
Copy link
Contributor

I know that #981 could bring some improvements, but I think it needs a lot of rewriting. Maybe it could be done after current functionality?

Yep not sure this will be done for the 2.0.0. This is just an idea.
And I guess if we decide to introduce something like this will be on top of current API in a first time. (I mean just a new way to handle the data but not a full rewrite of all decoder/encoder)

So my proposition is to create TimestampedLwM2mNodeList (the name can be always changed) which is resource-like node

I watched this.
I understand you tried this way because it's less impactful from an API perspective and it should work.
But as we are in development for a major release, we can break the API if needed.

My concern with this way is that :
a TimestampedLwM2mNodeList will be consider as a LwM2mResource.
I feel from a conceptual point of view this is not so true.

I mean it looks this doesn't really fit the LWM2M concept :

Root
    ├── Object
    │   └── ObjectInstance
    │       ├── MultipleResource 
    │       │   ├── ResourceInstance
    │       │   └── ResourceInstance
    │       └── SingleResource
    └── Object
        ├── ObjectInstance
        │   ├── SingleResource
        │   └── SingleResource
        └── ObjectInstance
            ├── SingleResource
            └── ...
    └── ...

E.g : an object instance does not hold a TimestampedLwM2mNodeList or TimestampedLwM2mResourceList

The idea of the TimestampedLwM2mNode is that you can timestamp a whole node.

e.g. if you observe the object 3 and you get an historical notification with several value of this object at different timestamp, you will get a list of Timestamped LwM2mObject.

I'm not sure I'm clear 😅
Do you have the same feeling ? (or maybe I missed something?)

The big picture

Let's step back and try to identify where we need this kind of data. I mean several timestamped node :

I guess that's all ? 🤔
I asked more details about timestamped value but for other feature this should be only 1 timestamp by node (OpenMobileAlliance/OMA_LwM2M_for_Developers#538 (comment))

I think about this again and SendRequest API use a map of path => node.
If we use TimestampedNode, using a map is no more adapted as we can have several time the same path.
So don't know how this should looks like for now thinking :

  1. replace map by something else ?
  2. add timestamp to node ? (opl/send_timestamp)
  3. think about a new API ? (New API to handle LWM2M Data. #981)

I agree with you let aside the 3. way for now.
Let's focus on the first one : "replace the map by something else"
Let's go for the "simple solution" : a map of map OR list of map OR map of list

We can imagine :

//  by timestamp first. (timestamp -> path -> node)
SortedMap<Long, Map <LwM2mPath, LwM2mNode>> timestampedNodes;
// OR
//   by path first. (path -> timestamp -> node)
Map<LwM2mPath,SortedMap<Long, LwM2mNode>> timestampedNodes;
// OR
//   by path first.  (list sorted by timestamp)
Map<LwM2mPath,List<TimestampedLwM2mNode>> timestampedNodes;

For ObserveComposite, I guess this is more timestamp first because this is like you merge several notification in one, and so you want to get each separate notification by timestamp

For Send Operation, I don't know which one make more sense.
but I guess we could use same API for both.

Another solution could be to replace this map of map but a custom dedicated class but is this like thinking about 3. (#981) ?

If there are some points which are not clear do not hesitate to ask.

@Michal-Wadowski
Copy link
Contributor Author

Oh, I see the case. I was focused primarily on SingleResource timestamp variation, but there are more options indeed. The solution have to be more generic though.
I wonder if we should add timestamp feature to existing nodes (Object, ObjectInstance, SingleResource etc) or make container like TimestampedLwM2mNode (probably with multiple timestamp/values, not single like one).

I'm thinking about #981 (comment) solution to add more flexibility to ease add timestamps to nodes.

@sbernard31
Copy link
Contributor

I wonder if we should add timestamp feature to existing nodes (Object, ObjectInstance, SingleResource etc) or make container like TimestampedLwM2mNode (probably with multiple timestamp/values, not single like one).

I also wonder what could be the best choice ? 🤔

Some thought about adding timestamp to node :

  • if we add timestamp to node we need to ensure that timestamp are consistent (e.g. an Object Instance and its resources should not have different timestamp value)
  • if we add timestamp to each node this will duplicate the information a lot
  • even if you add timestamp on node you will need a structure to hold several nodes, so I feel this just move the timestamp from this structure to the node but without too much benefits.

For those reasons for now, I think it does not pay off to put timestamp on the node itself. (but maybe I missed something?)

About a using a container, I think this is my preferred solution for now.
A simple way it to go with simple structure like (as explained above : #1192 (comment))

//  by timestamp first. (timestamp -> path -> node)
SortedMap<Long, Map <LwM2mPath, LwM2mNode>> timestampedNodes;
// OR
//   by path first. (path -> timestamp -> node)
Map<LwM2mPath,SortedMap<Long, LwM2mNode>> timestampedNodes;
// OR
//   by path first.  (list sorted by timestamp)
Map<LwM2mPath,List<TimestampedLwM2mNode>> timestampedNodes;

I think the first one should feet better (for reason exposed above, still in #1192 (comment))

Do you see any drawback with this SortedMap<Long, Map <LwM2mPath, LwM2mNode>> timestampedNodes; soluion ?

@Michal-Wadowski
Copy link
Contributor Author

I think the good idea is to not enforce implementation (don't break current api) whenever node has timestamp/history or not. My idea is to add timestamp/history information optionally. I mean if server receive one node or many nodes within the same path but differ timestamps (historical nodes) it could use the same api for both. In second scenario server just gets first (or last) node and ignore the other. But if server use historical-aware api it can access the whole history.

I think about optionally extend current node implementations (LwM2mObject, LwM2mObjectInstance, LwM2mSingleResource etc) with timestamp/history feature.

I'm currently working on POC to show myself if this approach make sense at all. I'll share details of this idea soon.

@Michal-Wadowski
Copy link
Contributor Author

I pushed POC opl/timestamp_api with proposition of API. Please ignore broken tests and hacked LwM2mNodeSenMLDecoder implementation for now.

Note API for LwM2mSingleResource: I introduced interface which keep original behaviour and two implementations: LwM2mSingleResourceImpl as original implementation and LwM2mSingleResourceTimestamped decorator which provide original behaviour and allows to access historical data if needed and timestamps if available.

Ultimately I want to remove TimestampedLwM2mNodeImpl.

@sbernard31
Copy link
Contributor

I looked at this and I still see exactly same problem that I try to described above ☝️ (#1192 (comment))

I don't think a TimestampedNode should be a Node.
I don't think a Tree like this is correct :

Root
├── Object
    └── ObjectInstance
        ├── SingleResourceTimestamped
        │   ├── SingleResource
        │   └── SingleResource
        ├── MultipleResource 
        │   ├── ResourceInstance
        │   └── ResourceInstance
        └── SingleResource

@Michal-Wadowski
Copy link
Contributor Author

The reason why I wanted to add timestamp behaviour to current Node (TimestampedNode as a Node) is that the interface SendListener uses method dataReceived(..., Map<String, LwM2mNode> data, ...) and there is no place to add timestamp information other than in Node. In that case we should add another method to SendListener to handle this kind of data?

@sbernard31
Copy link
Contributor

sbernard31 commented Feb 14, 2022

There is no place to add timestamp information other than in Node. In that case we should add another method to SendListener to handle this kind of data?

We just discover that timestamped value are allowed, so I think we can consider that previous API was not adapted.

Instead of adding a new method, I would just change this one :

void dataReceived(Registration registration, Map<String, LwM2mNode> data, SendRequest request);

by something like one of them :

// only historical data
void dataReceived(
     Registration registration,
     SortedMap<Long, Map <LwM2mPath, LwM2mNode>> historicalData,
     SendRequest request);

//  historical data + most recent one. 
// (I'm not sure about what we put in "mostRecentData", so maybe not a good idea)
void dataReceived(
      Registration registration,
      Map<String, LwM2mNode> mostRecentData, // or lastData
      SortedMap<Long, Map <LwM2mPath, LwM2mNode>> historicalData,
      SendRequest request);

// we rely on send request API only to get data 
void dataReceived(Registration registration, SendRequest request);

(Note that SendRequest API need also to be adapted pretty much in a same way)

@sbernard31
Copy link
Contributor

⚠️
I had timestamped notification usage in mind.
In ObserveResponse you can either get the content of the Notification (not timestamped) with getContent()
and/or getTimestamped data with getTimestampedLwM2mNode()
(see ObserveResponse Constructor)

I was thinking we can just do pretty much the same think here.
But I just figure out that we can not easily put data without timestamp in this kind of structure (SortedMap<Long, Map <LwM2mPath, LwM2mNode>> historicalData) ... 😖
⚠️

So should we a dedicated structure (e.g : TimestampedLwM2mNodes) which can hold several nodes with timestamped or not timestamped value?

The only drawback with this solution is that I feel this overlaps a little bit the LwM2mData idea.

@Michal-Wadowski
Copy link
Contributor Author

I'm not sure if we should use timestamps as primary key for nodes. For example if we have something like that:

[{
    "bn":"/4/0/", "bt":1000,
    "n":"0", "v":1, "t":1
},{
    "n":"1", "v":2, "t":2
},{
    "n":"2", "v":3, "t":3
}]

In listener we'll got three time-separated nodes:

-  t: 1001: {n: /4/0/0, v: 1}
-  t: 1002: {n: /4/0/1, v: 2}
-  t: 1003: {n: /4/0/2, v: 3}

Or is it a good approach though 🤔 ?

So should we a dedicated structure (e.g : TimestampedLwM2mNodes)

I think the dedicated classes are better idea than raw types because we have better control over this data and the representation. Maybe in getTimestampedLwM2mNode() we also should return timestamp->node/nodes map-like structure.

@sbernard31
Copy link
Contributor

sbernard31 commented Feb 16, 2022

The idea about timestamp first is to match the Observe-Composite case as explained above :

For ObserveComposite, I guess this is more timestamp first because this is like you merge several notification in one, and so you want to get each separate notification by timestamp

Maybe I was not clear but I understand that each inner notification should contains all node requested by the Observe-Composite request. (see http://www.openmobilealliance.org/release/LightweightM2M/V1_1_1-20190617-A/HTML-Version/OMA-TS-LightweightM2M_Core-V1_1_1-20190617-A.html#6-4-4-0-644-Observe-Composite-Operation)

For Send Operation I don't know is the best way.
With your example either we get :

-  t: 1001: {n: /4/0/0, v: 1}
-  t: 1002: {n: /4/0/1, v: 2}
-  t: 1003: {n: /4/0/2, v: 3}

OR

-  n: /4/0/0 : {t: 1001, v: 1}
-  n: /4/0/1: {t: 1002 , v: 2}
-  n: /4/0/2: { t: 1003:, v: 3}

I'm not sure what is the best, I guess some time you want value by timestamp and sometime by path.
If we need to choose, with my current understanding I will go with timestamp first (because of Observe-Composite case ☝️ )
But anyway if we create a dedicated structure, I think this will be hidden and then we could provide API to request data by timestamp or path correct ?

@Michal-Wadowski
Copy link
Contributor Author

Michal-Wadowski commented Feb 18, 2022

Ok, now everything is more clear for me. I'll prepare some solution (POC) with container that allows to access both approaches. And if we'll use container we don't need overloaded dataReceived() of SendListener interface. And maybe we can use that with Composite-Observe. It can be connected also with #981 idea later (now I want to focus mainly on current functionality).

@Michal-Wadowski
Copy link
Contributor Author

I created branch opl/send_timestamp3 with POC that use LwM2mData container idea.
I think LwM2mData container class is good idea because it hides details about internal data structure and allows to easily gets nodes in format what we want.
Current POC doesn't have multiple timestamped values implementation but it's ready for it.

@sbernard31
Copy link
Contributor

I think LwM2mData could be a good idea.

My only concern is that LwM2mData should fit all LWM2M use cases. So it will be a more large task to define this kind of new general API than just a specific one for Timestamped Nodes.

Currently I have on eye on OSCORE and I also try to think about a new better transport layer abstraction.
This second point will be a big task and very impacted one. (this will probably blow my mind 🤯)
I'm not sure it's a good idea to start another big task at the same time. (like LwM2mData)
So maybe not the good time to focus on LwM2mData for now ? Unless we postpone the transport layer abstraction to work on LwM2mData now ? but I feel LwM2mData is a more optional feature. For now I don't even know if LwM2mData will/should be part of Leshan v2.0.0. Maybe we can post-pone it to v3.0.0 (or we will just drop it because we will discover it does fit at all)

Anyway, maybe it's better to just introduce a more simple / specific Timestamped Nodes API.
I looked at your code and this is more or less what you did. I mean your LwM2mData is very different than the one described at #981. (Not based on TreeMap, no LwM2mValue abstraction)
So I guess you can keep with this kind of container but I feel you should just focus on Timestamped Nodes use cases.
If you go in that way, please do not call it LwM2mData but more something like TimestampedLwM2mNodes. (I would like to keep this name for #981)

@Michal-Wadowski
Copy link
Contributor Author

No problem, I'll rename the class to be more specific to the timestamp context I used in these changes. I used the LwM2mData name but I didn't mean to do all the functionalities described in #981. I just only noticed that class I created replaces Lists/Maps of nodes. Sorry for the confusion 😄
According to the order of tasks to do, after internal discussion the timestamp support is more important than OSCORE now.

@sbernard31
Copy link
Contributor

According to the order of tasks to do, after internal discussion the timestamp support is more important than OSCORE now.

Ok, I will try to help.
Just to be sure you need mainly support at server, client or both side ?

@Michal-Wadowski
Copy link
Contributor Author

Michal-Wadowski commented Feb 28, 2022

Ok, I will try to help.

Thanks a lot 😄

Just to be sure you need mainly support at server, client or both side ?

Mainly on server side but I think the client side also have to be supported (even for full integration testing).

@sbernard31
Copy link
Contributor

I don't know if you see the current NodeEncoder/Decoder interfaces
E.g. for Decoder :

  • NodeDecoder
  • TimestampedNodeDecoder
  • MultiNodeDecoder

Without thinking too much of this I would have added a new interface TimestampedMultiNodeDecoder ?
I think you can look at NodeDecoder/TimestampedNodeDecoder to inspire yourself

@Michal-Wadowski
Copy link
Contributor Author

Without thinking too much of this I would have added a new interface TimestampedMultiNodeDecoder ?

Oh my, you are absolutely right! I was focused too much on how to adjust current encoder/decoder. It ended up with replace many current node structures into LwM2mData/TimestampedLwM2mNodes. But adjusting just Send-around functionality and add specific encoder/decoder will simplify the solution so much.

Thanks a lot for this clue 😄! It really helps me a lot!

@Michal-Wadowski
Copy link
Contributor Author

Ok, I created final (I hope) solution opl/send_timestamp4 that implements multiple timestamped node decoder and send which uses it.

The code is not cleaned yet but I'll clean it up if you agree that this solution is ok.

@sbernard31
Copy link
Contributor

(I will look at this afternoon)

@sbernard31
Copy link
Contributor

I looked at this quickly, I think the general idea is good. 👍

Just maybe 1 impacting thing, currently all data structure (LwM2mNode, TimestampNode, ....) are immutable and I see that TimestampNodes are not. Maybe we should make it immutable too for consistency ?

@Michal-Wadowski
Copy link
Contributor Author

I created PR #1217 with solution of current issue

@sbernard31
Copy link
Contributor

@Michal-Wadowski with #1217 and #1218 we done with the server side.

Do you plan something more ?

  1. Add Timestamped Nodes support to Send Operation at Client side ?
  2. Add Timestamped Nodes support to Composite-Observe ?

For 1. I think we should create a new dedicated issue.
For 2. we can use #1089.

Let me know ;)

About this issue, I think we can close it now ?

@Michal-Wadowski
Copy link
Contributor Author

Do you plan something more ?

1. Add Timestamped Nodes support to Send Operation at **Client side** ?

Yes, our team will be working on this topic. I'm personally be switching to other project but I'll be helping a little bit.

For 1. I think we should create a new dedicated issue

I agree.

About this issue, I think we can close it now ?

Yes, I'll close issue.

@sbernard31
Copy link
Contributor

Yes, our team will be working on this topic.

OK ✔️ I created a dedicated issue : #1228

I'm personally be switching to other project but I'll be helping a little bit.

Nooooo

Such a bad news for Leshan project... 😞

Thx again for your work on Leshan 🙏, I hope you will be able to work again with us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Any question about leshan
Projects
None yet
Development

No branches or pull requests

2 participants