Coder Social home page Coder Social logo

Comments (8)

Katrix avatar Katrix commented on July 26, 2024

Can you show me you command object? Most likely the issues lie in there somewhere. I've been dealing with this myself recently for a retry flow. From my testing, the cause is normally a Source.single together with a flatMapConcat somewhere. Why it happens I can't say though. Most likely some Akka. I've been able to work around it for my stuff by avoiding Source.single together with flatMapConcat.

As for if there is a better way to do this, have you looked at the alsoTo method on flow? You could also just be lazy and do one operation after the other (take advantage of the request context and the withContext method on Request to simplify this).

Going to leave this open until I either find a solution to this problem, and know the root cause for why it happens and what can be done to avoid it.

from ackcord.

Bathtor avatar Bathtor commented on July 26, 2024

I updated the original post with the full actor. The relevant command factories are:

def charCmdFactory(sayAsActor: ActorRef): ParsedCmdFactory[F, SayAsCmd.CharacterArgs, NotUsed] =
    ParsedCmdFactory[F, SayAsCmd.CharacterArgs, NotUsed](
      refiner = CmdInfo[F](
        prefix = Categories.adminCommands,
        aliases = Seq("char"),
        filters = Seq(ByUser(UserId(Main.adminId)))),
      sink = _ => Sink.actorRefWithAck(
        ref = sayAsActor,
        onInitMessage = SayAsCmd.InitAck,
        ackMessage = SayAsCmd.Ack,
        onCompleteMessage = PoisonPill),
      description = Some(CmdDescription(
        name = "Character Registry",
        description = "Add/Remove/List Characters",
        usage = "register <name> [<avatar url>]|unregister <name>|list")));

def sayasCmdFactory(sayAsActor: ActorRef): ParsedCmdFactory[F, SayAsCmd.SayArgs, NotUsed] =
    ParsedCmdFactory[F, SayAsCmd.SayArgs, NotUsed](
      refiner = CmdInfo[F](
        prefix = Categories.generalCommands,
        aliases = Seq("sayas")),
      sink = _ => Sink.actorRefWithAck(
        ref = sayAsActor,
        onInitMessage = SayAsCmd.InitAck,
        ackMessage = SayAsCmd.Ack,
        onCompleteMessage = PoisonPill),
      description = Some(CmdDescription(
        name = "SayAs",
        description = "Speak as a registered character",
        usage = "<name> <text>")));

I'm not using Source.single anywhere, I think, unless there is somehow one hidden in mapAsyncUnordered?

I was originally planning to use alsoTo with filter, but then I found Unzip which fit my use-case much better. Doing them lazily is not so easy, I think. I only want the delete to occur if the reply is happening as well (so that a semantically invalid command will not get deleted), and I also need to keep the required state around to create the correct delete object (i.e. messageId and channelId).

from ackcord.

Bathtor avatar Bathtor commented on July 26, 2024

I also find it curious, that it's always the delete flow that fails, even if I switch the positions in the Unzip. I mean the two branches are essentially identical except for the mapConcat. The sinks have different serialisation types, but apart from that they are the same implementation, aren't they? Why would one misbehave and the other work fine?

Edit: I tried unzip.out1.mapConcat(dm => List(dm)).log("DELETE MSG", dm => dm.messageId) ~> deleteSink; just to make sure that the mapConcat wasn't the difference, and indeed the behaviour persists.

from ackcord.

Katrix avatar Katrix commented on July 26, 2024

My only guess would be that mapConcat has some of the same logic to cause the same error. As for what I said above, when Is aid being lazy I meant more not worry about doing things properly. As for keeping the required state around, that's what withContext is for.

As for the types being different. Yep, that's the only difference. On master it's just the same flow/sink casted to different types.

from ackcord.

Bathtor avatar Bathtor commented on July 26, 2024

Is there a common supertype I could use for a sink that would make it possible to use a single flow for both CreateMessage and DeleteMessage?

from ackcord.

Katrix avatar Katrix commented on July 26, 2024

Request[_, _], BaseRESTRequest[_, _, _] and RESTRequest[_, _, _, _] would all fit.

from ackcord.

Bathtor avatar Bathtor commented on July 26, 2024

Ok, I made a single flow now for both message types like this:

private val msgQueue = Source.queue[(ActorRef, SayAsMessage, ChannelId, MessageId)](32, OverflowStrategy.backpressure)
    .mapAsyncUnordered(parallelism = 1000)((t: (ActorRef, SayAsMessage, ChannelId, MessageId)) =>
      (t._1 ? t._2).mapTo[List[CreateMessageData]].map(l => (DeleteMessage(t._3, t._4) :: l.map(CreateMessage(t._3, _)))))
    .mapConcat(identity)
    .to(requests.sinkIgnore[Any, NotUsed]).run();

But once again only the first exchange works, and then the flow simply stops executing any requests (i.e. neither DeleteMessage nor CreateMessage are executed after the first time, when both are successfully executed). I don't know why, but DeleteMessage somehow breaks the sink, without throwing any errors that I can see (I'll attach my logging output, maybe you see something I've overlooked). I don't see this behaviour if the flow consists only of CreateMessage requests. In that case it keeps working correctly forever.
output.log
Edit: I'm using a local build of master, btw, not 0.10.0.

from ackcord.

Katrix avatar Katrix commented on July 26, 2024

Retry requests fixes on master. Not sure how much it was ever related to this bug, but that should be the last "Stream stopped for some reason" kind of bug.

from ackcord.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.