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

Queue#peek1 and timedPeek1 #996

Merged
merged 4 commits into from
Nov 26, 2017
Merged

Queue#peek1 and timedPeek1 #996

merged 4 commits into from
Nov 26, 2017

Conversation

durban
Copy link
Contributor

@durban durban commented Nov 25, 2017

Queue#peek1 and timedPeek1 (fixes #983).

I'm unsure about the semantics for synchronous (and consequently for synchronousNoneTerminated). If I understand correctly, that queue is (conceptually) always empty. That would suggest, that peek1 should never finish. However, it is in fact possible (sometimes) to dequeue an element from such a queue. Thus, peek could also work. This seems more useful, so this is what this PR currently implements.

@SystemFw SystemFw self-assigned this Nov 25, 2017
}

private def peek1Impl: F[Either[Ref[F, A], A]] = ref[F, A].flatMap { ref =>
qref.modify2 { state =>
Copy link
Collaborator

Choose a reason for hiding this comment

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

For consistency, I'd rather this follow the pattern of dealing with state and output separately, using modify. This will also allow for some simplification

}

def dequeue1: F[A] = cancellableDequeue1.flatMap { _._1 }

def peek1: F[A] = peek1Impl.flatMap {
case Left(ref) => ref.get
Copy link
Collaborator

Choose a reason for hiding this comment

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

this can be just a fold

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean like .flatMap(_.fold(_.get, F.pure))? Pattern matching is supposedly faster; but if fold is preferred in this codebase, I can change it.

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 think it will make a big difference (unless I see numbers), but I also don't think is something to get hung up on if you don't like the change (and yes, .flatMap(_.fold(_.get, F.pure))). The only important points are modify vs modify2, and whether we should have a cancellablePeek or not

// queue was empty, we had waiting dequeuers
c.previous.deq.head.setAsyncPure(Chunk.singleton(a))
}
val pk = if (c.previous.peek.isEmpty) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you want, you can fold or map(...).getOrElse on c.previous.peek here, since it's an Option. Not a big deal though

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've used isEmpty/get to conform to the already existing code there (which uses isEmpty/head).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fair enough :)

final case class State(
queue: Vector[A],
deq: Vector[Ref[F,Chunk[A]]],
peek: Option[Ref[F, A]]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Adding a @param for this as well would be nice, for consistency

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok.

}
}.map(_._2)
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Generally speaking I like the approach here, not sure whether we should go the full route of having a cancellablePeek1 like for dequeue or not

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll think about it.

@SystemFw
Copy link
Collaborator

SystemFw commented Nov 25, 2017

Generally I like the approach, left a few comments. From an implementation point of view peek1 on synchronous queues is ok. It's just unlikely to be very useful

@durban
Copy link
Contributor Author

durban commented Nov 26, 2017

I've pushed a commit addressing (hopefully) all comments, except the one about cancellable peek. I'll have to think about that one. (Actually I wish there was a general way of cancelling async stuff, not implementing separately one variant for every method...)

else state
}.map { change =>
if (change.previous.queue.isEmpty) Left(change.now.peek.get)
else Right(change.now.queue.head)
Copy link
Collaborator

Choose a reason for hiding this comment

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

One super minor nitpick (sorry). change.previous.queue.head for symmetry with the isEmpty (since the queue hasn't changed between previous and 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.

Fair enough.

@SystemFw
Copy link
Collaborator

SystemFw commented Nov 26, 2017

Apart from one extra little comment, it's ready. Thank you very much for this :)
I'm thinking of merging as is (+ change.previous.queue), and reassess the cancellable thing later. I'd also prefer composable cancellation, but it's a problem we should address in cats-effect (we are talking about it).

@@ -16,3 +16,4 @@ Also see the [GitHub contributor stats](https://github.com/functional-streams-fo
- Rúnar Ó. Bjarnason ([@runarorama](https://github.com/runarorama)): Various processes and combinators, circular buffers, compression. I'm an ideas man, Michael.
- Jed Wesley-Smith ([@jedws](https://github.com/jedws)): really very minor tweaks, cleanups and pestering, hardly worth the mention
- Michael Pilquist ([@mpilquist](https://github.com/mpilquist)): 0.9 redesign work, maintenance
- Daniel Urban ([@durban](https://github.com/durban)): queue peek implementation
Copy link
Member

Choose a reason for hiding this comment

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

Add to build.sbt too so it shows up in the generated POM.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, thanks.

Copy link
Collaborator

Choose a reason for hiding this comment

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

lol I need to remember to do that as well at some point

@mpilquist mpilquist merged commit 8cca91d into typelevel:series/0.10 Nov 26, 2017
@mpilquist
Copy link
Member

Looks great, thanks

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.

3 participants