Skip to content

Refactor conversations#40

Closed
kaichaosun wants to merge 8 commits intomainfrom
refactor-inbox
Closed

Refactor conversations#40
kaichaosun wants to merge 8 commits intomainfrom
refactor-inbox

Conversation

@kaichaosun
Copy link
Contributor

What changes:

  • renaming traits related to ConvFactory
  • move shared traits to common submodule
  • inbox, dm(direct message), group split
  • fix dead code
  • isolate FFI into submodule
  • restructure prost related bytes conversion

@kaichaosun kaichaosun requested review from jazzz and osmaczko February 3, 2026 07:00
Copy link
Collaborator

@jazzz jazzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's hard to understand the motivation behind these changes, and the reason why to change it now.

I can see that you are focusing on better organization of the project, which is welcome as the project could use improvements - However I don't grok why this path is preferred.

Clearly articulating the motivations would allow discussions to occur.

Sticky points:

  • Conversation != Session, they are not substitutable.
  • Trait Renaming doesn't accurately describe what is happening.
  • Folder structure logic, I don't understand the vision.

Comment on lines 38 to 39
impl HasConversationId for PrivateV1Convo {
fn id(&self) -> SessionId<'_> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Session is not the correct term to use here.

Session refers to a double-ratchet state shared between two participants.

Conversation is an abstract way to communicate between clients.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, session seems not fit, I may find a new name, feel free to recomment new ones.
Conversation seems long, a short one would be good.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may find a new name, feel free to recomment new ones.

Unfortunately Conversation is the best I have 😄 - which is why its used everywhere.

Conversation seems long, a short one would be good.

I shortened it to Convo as i figured the team would want something shorter 😅

@@ -0,0 +1 @@
pub mod privatev1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed I don't think converting this crate to legacy style modules adds any value, and makes working in the project more difficult. I understand there is not agreement on this topic, but I don't see a need to force this change now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This crate clearly scope related logic in its own directory, without growing the files in src folder, and no need to just around to understand about the related logic.
The value is meaning in my opinion, do you mind switch to this branch in local and try it a bit, and see if you like it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mind switch to this branch in local and try it a bit, and see if you like it?
I will gladly give it another try.
However this is not my first experience. I've worked in projects with both approaches. I think they both have pros - I don't deny that the approach you are suggesting has its merits.

I don't see a need to force this change now.

My main point is that this doesn't seem like a blocking item, it seems like personal preference. Given the current work load this seems low priority. There are many issues with imports and code structure which have larger impacts that we can agree on have benefit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The restructure helps assemble my mind, the reason has been discussed in different places.

And this is my overall plan to go through this journey,

  1. refactor structure, isolate ffi, clear code and naming
  2. refactor api include Context (I don't have clear idea how to do it, but looks like have to, because the convo_handle_map needs to be persisted somehow).
  3. then in this stage, we will have clear data model that's worth to be persisted. (Or maybe just persist the hash map with KV is also acceptable? But remember data migration is hard, and reasonable data model helps everyone in long journey.)

use rand_core::{CryptoRng, RngCore};

use crate::crypto::{PublicKey, StaticSecret};
use crate::identity::{PublicKey, StaticSecret};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Sand] I don't have a blocker here - but Identity doesn't seem like the correct place to manage Keys.

crypto was a wrapper around the crate to isolate dependencies. If the wrapper is not desired, then the crypto crate should be imported directly.

payload: proto::EncryptedPayload,
) -> Result<(SecretKey, proto::InboxV1Frame), ChatError> {
let handshake = Self::extract_payload(payload)?;
let payload_bytes = handshake.payload.clone();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why clone here, instead of consuming the slice directly?

enc_payload: proto::InboxHandshakeV1,
) -> Result<proto::InboxV1Frame, ChatError> {
let frame_bytes = enc_payload.payload;
fn decrypt_frame(payload_bytes: prost::bytes::Bytes) -> Result<proto::InboxV1Frame, ChatError> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change, weakens the type constraint on the function - Making auto complete more difficult and adding new failure modes to this function.

Whats the motivation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function is not used before, I'm trying to use it in some way, so it don't get deleted or become dangling code.

Copy link
Collaborator

@jazzz jazzz Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so it don't get deleted

Then I would delete it. I don't see much harm in that. Changing the signature to accept a more generic type (Bytes)loses context which is more harmful.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow up here. I looked into this when solving another problem and realized I had missed the intention here.

I now see that the type constraint cannot be maintained easily. Changing the decrypt_frame function to accept Bytes was a good move in my opinion.


// Used by Conversations to attach addresses to outbound encrypted payloads
pub(crate) struct AddressedEncryptedPayload {
pub struct AddressedEncryptedPayload {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why its required to expose an exclusively internal type outside of the crate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compiler complains about it being internal public after change a few modules to be public.

Comment on lines +1 to +6
pub mod common;
pub mod dm;
pub mod ffi;
pub mod group;
pub mod inbox;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Boulder] Why expose internal implementation details? This will make maintenance of the library more difficult. I don't understand why this would be desirable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is trying to solve unused code without adding #![allow(dead_code)] everywhere.

I agree it's not the best solution, since we don't fully understand the dev experience yet (used as a Rust library), this may also help bring some discussion about the internal design of logos-chat.

The library is early, broken changes is not problem in my opinion.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is trying to solve unused code without adding #![allow(dead_code)] everywhere.

The deadcode is there because core functionality is not yet completed. Which needs to be done in the next 2 weeks. If thats too long, then I'd say remove all the offending code completely.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how "common" is an improvement. The crate already has a "utils", "types" files which are intended to hold components useful to many modules. Having all three makes it unclear of where code ought to live.

In this case, Common doesn't seem common at all. It seems only to pertain to Conversations

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Common is shared by different types of conversations like inbox, dm and group chat.
The logos-chat (this crate) is about chat related protocols, and the major business logic is around inbox and dm, the common module is shared trait definitions depend by the major business.

The shared types may also fit into common, but it may grow and better in split module for now.

Copy link
Collaborator

@jazzz jazzz Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously this code was in a file conversation.rs and the conversation types were submodules that sub-modules of Conversation.

Moving this code out of the Conversations Module seems to be the opposite of logically grouping business logic. It was contained logically and now its not.

by different types of conversations like inbox

Inbox is not a Conversation - Its the component which initializes conversations. It consumed the conversation module just as the Client module does. Though I will admit that Inbox is not perfect there is much to clean up after persistence is implemented.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the motivation on flattening the "Conversation" folder which contained conversations into these hyper-specific root level modules.

  • This exposes the root of the project to more folders. Will future folders include things like "broadcast", and "communities"?
  • This destroys the logical grouping of related components. Flattening to: "Group","storage", "dm", "broadcast", "communities", "ffi" seems harder to follow what is happening in the crate than "conversations", "storage", "ffi".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the part bothering you is the crate being named "conversations"? Would renaming that to "context", "client", "chat" help at all?

Copy link
Contributor Author

@kaichaosun kaichaosun Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The confusing part is the unclear relationship between conversations and inbox, before make it clear, we should flatten the modules.

Also I don't think the library will grow enough to the need of have 3 layers directory like src/conversation/xyz, each layer needs clear abstraction, and we should first improve on the use of secondary one which is dm, inbox, and group for now. Even adding broadcast and communities, or a few others is not a problem, because most devs only need to care about the directory the need, and this also justifies the need to not depend on a inbox.rs (other module based file) in src.

Copy link
Contributor Author

@kaichaosun kaichaosun Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea to use chat to replace conversations. The flatten modules are still needed though.

@kaichaosun
Copy link
Contributor Author

kaichaosun commented Feb 4, 2026

It's hard to understand the motivation behind these changes, and the reason why to change it now.

  • by running the code before, there are clearly warnings in a lot of places. And I really want to see the codebase has very little even 0 warnings if possible.
  • after reading through the code, the FFI logic is taking focus from me to understand the functional business logic.
  • I need to jump around different places to understand how the a single business like privatev1 works.
  • want to adding storage directly, really hard to find the necessary fields to save.

So I think maybe the codebase needs such refactor to help other devs to run and reason about the code. The namings introduced in this PR is definitely not final or best, it's just a place to discuss and try make it more clear before more users reading on it.

It takes good energy to think about most items introduced in this PR, it may not reflect other's coding styling, but my motivation is to make the codebase as perfect as I can. BTW most items is handmade, AI helps with some namings and docs. (I don't trust AI on refactor for now)

@jazzz
Copy link
Collaborator

jazzz commented Feb 4, 2026

@kaichaosun

It takes good energy to think about most items introduced in this PR, it may not reflect other's coding styling, but my motivation is to make the codebase as perfect as I can.

I see that. Its very clear that is your goal - and I'm grateful thats where your mind is. I think there are good changes in here. But its hard to see.

by running the code before, there are clearly warnings in a lot of places. And I really want to see the codebase has very little even 0 warnings if possible.

I would suggest that could have been a dedicated PR - as the changes are narrow in scope. That would allow discussion and make it easier to find alignment.

after reading through the code, the FFI logic is taking focus from me to understand the functional business logic.

I understand its not great. That part is evolving quickly, and there are lots of changes. The API file will eventually need to be exported to a crate but its not finished yet. I'd like to get it working before we start moving things around. It's my current focus, perhaps we can ignore api.rs and a few types in context.rs for now? If there are blockers lets discuss.

I need to jump around different places to understand how the a single business like privatev1 works.

Perhaps we can book a Pairing-Session to go over this. I don't understand the exact friction - but would like to learn more.

want to adding storage directly, really hard to find the necessary fields to save.

Thats fair. I could see it being unclear. Especially since functionality is not complete.
I would focus on making smaller problems; Go protocol by protocol and ensure that they can survive a restart. Starting with PrivateV1 . Participant information is missing but that can be added after. If there are questions lets use the tracking ticket to have those discussions and gather the needed requirements.

@kaichaosun
Copy link
Contributor Author

Replaced by other PRs.

@kaichaosun kaichaosun closed this Feb 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants