Thanks for updating the KIP. I think there is still one open question. `suppress()` can be used on non-windowed KTable for rate control, as well as on a windowed-KTable (also for rate control, but actually mainly) for only emitting the final result of a windowed aggregation. For the non-windowed case, we use a KeyValueStore while for the windowed cases, we use a WindowStore.
Because there is no final result for non-windowed KTables, it seems that this new feature only make sense for the windowed-aggregation case? Thus, the signature of `Materialized` should take a `WindowStore` instead of a `KeyValueStore`? If that's correct, I am wondering: - Can we guard from a miss-usage of the API if the upstream KTable is not windowed (or maybe it's not necessary to guard)? - Can we actually implement it? We had issues with regard to KIP-300 to materialize windowed-KTables? Would be worth to clarify upfront. Maybe, we even need a POC implementation to verify that it works? -Matthias On 9/11/20 12:26 AM, Dongjin Lee wrote: > Hi All, > > Here is the voting thread: > https://lists.apache.org/thread.html/r5653bf2dafbb27b247bf20dbe6f070c151b3823d96c9c9ca94183e20%40%3Cdev.kafka.apache.org%3E > > Thanks, > Dongjin > > On Fri, Sep 11, 2020 at 4:23 PM Dongjin Lee <dong...@apache.org> wrote: > >> Hi John, >> >> Thanks for the feedback. I will open the Vote thread now. >> >> Best, >> Dongjin >> >> On Fri, Sep 11, 2020 at 2:00 AM John Roesler <vvcep...@apache.org> wrote: >> >>> Hi Dongjin, >>> >>> Sorry for the delay. I'm glad you're still pushing this >>> forward. It would be nice to get this in to the 2.7 release. >>> >>> I just took another look at the KIP, and it looks good to >>> me! >>> >>> I think this is ready for a vote. >>> >>> Thanks, >>> -John >>> >>> On Wed, 2020-08-05 at 22:04 +0900, Dongjin Lee wrote: >>>> Hi All, >>>> >>>> I updated the KIP >>>> < >>> https://cwiki.apache.org/confluence/display/KAFKA/KIP-508%3A+Make+Suppression+State+Queriable >>>> >>>> and the implementation, following the discussion here. >>>> >>>> You must be working hard preparing the release of 2.6.0, so please have >>> a >>>> look after your work is done. >>>> >>>> Thanks, >>>> Dongjin >>>> >>>> On Sun, Mar 8, 2020 at 12:20 PM John Roesler <vvcep...@apache.org> >>> wrote: >>>> >>>>> Thanks Matthias, >>>>> >>>>> Good idea. I've changed the ticket name and added a note >>>>> clarifying that this ticket is not the same as >>>>> https://issues.apache.org/jira/browse/KAFKA-7224 >>>>> >>>>> Incidentally, I learned that I never documented my reasons >>>>> for abandoning my work on KAFKA-7224 ! I've now updated >>>>> that ticket, too, so your question had an unexpected side-benefit. >>>>> >>>>> Thanks, >>>>> -John >>>>> >>>>> On Sat, Mar 7, 2020, at 18:01, Matthias J. Sax wrote: > Thanks for clarification. > > Can you maybe update the Jira ticket? Do we have a ticket for > spill-to-disk? Maybe link to it and explain that it's two different > things? Maybe even rename the ticket to something more clear, ie, > "make suppress result queryable" or simliar? > > > -Matthias > > On 3/7/20 1:58 PM, John Roesler wrote: >>>>>>>> Hey Matthias, >>>>>>>> >>>>>>>> I’m sorry if the ticket was poorly stated. The ticket is to add a > DSL overload to pass a Materialized argument to suppress. As a >>>> result, > the result of the suppression would be queriable. >>>>>>>> This is unrelated to “persistent buffer” aka “spill-to-disk”. >>>>>>>> >>>>>>>> There was some confusion before about whether this ticket could be > implemented as “query the buffer”. Maybe it can, but not trivially. > The obvious way is just to add a new state store which we write the > results into just before we forward. I.e., it’s exactly like the > materialized variant of any stateless KTable operation. >>>>>>>> Thanks, John >>>>>>>> >>>>>>>> On Sat, Mar 7, 2020, at 15:32, Matthias J. Sax wrote: Thanks for >>>>>>>> the KIP Dongjin, >>>>>>>> >>>>>>>> I am still not sure if I can follow, what might also be caused by >>>>>>>> the backing JIRA ticket (maybe John can clarify the intent of the >>>>>>>> ticket as he created it): >>>>>>>> >>>>>>>> Currently, suppress() only uses an in-memory buffer and my >>>>>>>> understanding of the Jira is, to add the ability to use a >>>>>>>> persistent buffer (ie, spill to disk backed by RocksDB). >>>>>>>> >>>>>>>> Adding a persistent buffer is completely unrelated to allow >>>>>>>> querying the buffer. In fact, one could query an in-memory buffer, >>>>>>>> too. However, querying the buffer does not really seem to be >>>> useful >>>>>>>> as pointed out by John, as you can always query the upstream >>>> KTable >>>>>>>> store. >>>>>>>> >>>>>>>> Also note that for the emit-on-window-close case the result is >>>>>>>> deleted from the buffer when it is emitted, and thus cannot be >>>>>>>> queried any longe r. >>>>>>>> >>>>>>>> >>>>>>>> Can you please clarify if you intend to allow spilling to disk or >>>>>>>> if you intent to enable IQ (even if I don't see why querying make >>>>>>>> sense, as the data is either upstream or deleted). Also, if you >>>>>>>> want to enable IQ, why do we need all those new interfaces? The >>>>>>>> result of a suppress() is a KTable that is the same as any other >>>>>>>> key-value/windowed/sessions store? >>>>>>>> >>>>>>>> We should also have corresponding Jira tickets for different cases >>>>>>>> to avoid the confusion I am in atm :) >>>>>>>> >>>>>>>> >>>>>>>> -Matthias >>>>>>>> >>>>>>>> >>>>>>>> On 2/27/20 8:21 AM, John Roesler wrote: >>>>>>>>>>> Hi Dongjin, >>>>>>>>>>> >>>>>>>>>>> No problem; glad we got it sorted out. >>>>>>>>>>> >>>>>>>>>>> Thanks again for picking this up! -John >>>>>>>>>>> >>>>>>>>>>> On Wed, Feb 26, 2020, at 09:24, Dongjin Lee wrote: >>>>>>>>>>>>> I was under the impression that you wanted to expand the >>>>>>>>>>>>> scope of the KIP >>>>>>>>>>>> to additionally allow querying the internal buffer, not >>>>>>>>>>>> just the result. Can you clarify whether you are proposing >>>>>>>>>>>> to allow querying the state of the internal buffer, the >>>>>>>>>>>> result, or both? >>>>>>>>>>>> >>>>>>>>>>>> Sorry for the confusion. As we already talked with, we >>>> only >>>>>>>>>>>> need to query the suppressed output, not the internal >>>>>>>>>>>> buffer. The current implementation is wrong. After >>>> refining >>>>>>>>>>>> the KIP and implementation accordingly I will notify you - >>>>>>>>>>>> I must be confused, also. >>>>>>>>>>>> >>>>>>>>>>>> Thanks, Dongjin >>>>>>>>>>>> >>>>>>>>>>>> On Tue, Feb 25, 2020 at 12:17 AM John Roesler >>>>>>>>>>>> <vvcep...@apache.org> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dongjin, >>>>>>>>>>>>> >>>>>>>>>>>>> Ah, I think I may have been confused. I 100% agree that >>>>>>>>>>>>> we need a materialized variant for suppress(). Then, you >>>>>>>>>>>>> could do: ...suppress(..., >>>>>>>>>>>>> Materialized.as(“final-count”)) >>>>>>>>>>>>> >>>>>>>>>>>>> If that’s your proposal, then we are on the same page. >>>>>>>>>>>>> >>>>>>>>>>>>> I was under the impression that you wanted to expand the >>>>>>>>>>>>> scope of the KIP to additionally allow querying the >>>>>>>>>>>>> internal buffer, not just the result. Can you clarify >>>>>>>>>>>>> whether you are proposing to allow querying the state of >>>>>>>>>>>>> the internal buffer, the result, or both? >>>>>>>>>>>>> >>>>>>>>>>>>> Thanks, John >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, Feb 20, 2020, at 08:41, Dongjin Lee wrote: >>>>>>>>>>>>>> Hi John, Thanks for your kind explanation with an >>>>>>>>>>>>>> example. >>>>>>>>>>>>>> >>>>>>>>>>>>>>> But it feels like you're saying you're trying to do >>>>>>>>>>>>>>> something different >>>>>>>>>>>>>> than just query the windowed key and get back the >>>>>>>>>>>>>> current count? >>>>>>>>>>>>>> >>>>>>>>>>>>>> Yes, for example, what if we need to retrieve the (all >>>>>>>>>>>>>> or range) keys >>>>>>>>>>>>> with >>>>>>>>>>>>>> a closed window? In this example, let's imagine we >>>> need >>>>>>>>>>>>>> to retrieve only (key=A, window=10), not (key=A, >>>>>>>>>>>>>> window=20). >>>>>>>>>>>>>> >>>>>>>>>>>>>> Of course, the value accompanied by a flushed key is >>>>>>>>>>>>>> exactly the same to the one in the upstream KTable; >>>>>>>>>>>>>> However, if our intention is not pointing out a >>>>>>>>>>>>>> specific key but retrieving a group of unspecified >>>>>>>>>>>>>> keys, we stuck >>>>>>>>>>>>> in >>>>>>>>>>>>>> trouble - since we can't be sure which key is flushed >>>>>>>>>>>>>> out beforehand. >>>>>>>>>>>>>> >>>>>>>>>>>>>> One workaround would be materializing it with >>>>>>>>>>>>>> `suppressed.filter(e -> >>>>>>>>>>>>> true, >>>>>>>>>>>>>> Materialized.as("final-count"))`. But I think >>>> providing >>>>>>>>>>>>>> a materialized variant for suppress method is better >>>>>>>>>>>>>> than this workaround. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Thanks, Dongjin >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Feb 20, 2020 at 1:26 AM John Roesler >>>>>>>>>>>>>> <vvcep...@apache.org> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> Thanks for the response, Dongjin, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I'm sorry, but I'm still not following. It seems >>>> like >>>>>>>>>>>>>>> the view you >>>>>>>>>>>>> would >>>>>>>>>>>>>>> get on the "current state of the buffer" would >>>> always >>>>>>>>>>>>>>> be equivalent to the view of the upstream table. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Let me try an example, and maybe you can point out >>>>>>>>>>>>>>> the flaw in my reasoning. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Let's say we're doing 10 ms windows with a grace >>>>>>>>>>>>>>> period of zero. Let's also say we're computing a >>>>>>>>>>>>>>> windowed count, and that we have a "final results" >>>>>>>>>>>>>>> suppression after the count. Let's materialize the >>>>>>>>>>>>>>> count as "Count" and the suppressed result as "Final >>>>>>>>>>>>>>> Count". >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Suppose we get an input event: (time=10, key=A, >>>>>>>>>>>>>>> value=...) >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Then, Count will look like: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> window | key | value | | 10 | A | 1 | >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> The (internal) suppression buffer will contain: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> window | key | value | | 10 | A | 1 | >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> The record is still buffered because the window >>>>>>>>>>>>>>> isn't closed yet. Final Count is an empty table: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> window | key | value | >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> --------------- >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Now, we get a second event: (time=15, key=A, >>>>>>>>>>>>>>> value=...) >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Then, Count will look like: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> window | key | value | | 10 | A | 2 | >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> The (internal) suppression buffer will contain: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> window | key | value | | 10 | A | 2 | >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> The record is still buffered because the window >>>>>>>>>>>>>>> isn't closed yet. Final Count is an empty table: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> window | key | value | >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> --------------- >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Finally, we get a third event: (time=20, key=A, >>>>>>>>>>>>>>> value=...) >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Then, Count will look like: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> window | key | value | | 10 | A | 2 | | >>>>>>>>>>>>>>> 20 | A | 1 | >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> The (internal) suppression buffer will contain: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> window | key | value | | 20 | A | 1 | >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Note that window 10 has been flushed out, because >>>>>>>>>>>>>>> it's now closed. And window 20 is buffered because >>>> it >>>>>>>>>>>>>>> isn't closed yet. Final Count is now: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> window | key | value | | 10 | A | 2 | >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> --------------- >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Reading your email, I can't figure out what value >>>>>>>>>>>>>>> there is in querying >>>>>>>>>>>>> the >>>>>>>>>>>>>>> internal suppression buffer, since it only contains >>>>>>>>>>>>>>> exactly the same >>>>>>>>>>>>> value >>>>>>>>>>>>>>> as the upstream table, for each key that is still >>>>>>>>>>>>>>> buffered. But it feels >>>>>>>>>>>>> like >>>>>>>>>>>>>>> you're saying you're trying to do something >>>> different >>>>>>>>>>>>>>> than just query >>>>>>>>>>>>> the >>>>>>>>>>>>>>> windowed key and get back the current count? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Thanks, -John >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Wed, Feb 19, 2020, at 09:49, Dongjin Lee wrote: >>>>>>>>>>>>>>>> Hi John, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> 'The intermediate state of the suppression' in KIP >>>>>>>>>>>>>>>> does not mean the >>>>>>>>>>>>>>> state >>>>>>>>>>>>>>>> of upstream KTable - sure, the state of the >>>>>>>>>>>>>>>> upstream KTable can be >>>>>>>>>>>>>>> queried >>>>>>>>>>>>>>>> by materializing the operator immediately before >>>>>>>>>>>>>>>> the suppress as you >>>>>>>>>>>>>>> shown. >>>>>>>>>>>>>>>> What I meant in KIP was the final state of the >>>>>>>>>>>>>>>> buffer, which is not >>>>>>>>>>>>>>> emitted >>>>>>>>>>>>>>>> yet. (I agree, the current description may be >>>>>>>>>>>>>>>> confusing; it would be >>>>>>>>>>>>>>> better >>>>>>>>>>>>>>>> to change it with 'the current state of the >>>>>>>>>>>>>>>> suppression' or 'the >>>>>>>>>>>>> results >>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>> the suppression', like the Jira issue >>>>>>>>>>>>>>>> <https://issues.apache.org/jira/browse/KAFKA-8403 >>>>> >>>>>>>>>>>>>>>> states.) >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> For a little bit more about the motivation, here >>>> is >>>>>>>>>>>>>>>> one of my >>>>>>>>>>>>>>> experience: I >>>>>>>>>>>>>>>> had to build a monitoring application which >>>>>>>>>>>>>>>> collects signals from IoT devices (say, a >>>>>>>>>>>>>>>> semiconductor production line.) If the number of >>>>>>>>>>>>>>> collected >>>>>>>>>>>>>>>> signals within the time window is much less than >>>>>>>>>>>>>>>> the expected, there >>>>>>>>>>>>> may >>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>> some problems like network hiccup in the systems. >>>>>>>>>>>>>>>> We wanted to build >>>>>>>>>>>>> the >>>>>>>>>>>>>>>> system in the form of a dashboard, but could not >>>> by >>>>>>>>>>>>>>>> lack of >>>>>>>>>>>>> materializing >>>>>>>>>>>>>>>> feature. It was precisely the case of querying >>>> only >>>>>>>>>>>>>>>> the final >>>>>>>>>>>>> results of >>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>> windowed aggregation, as the Jira issue >>>>>>>>>>>>>>>> <https://issues.apache.org/jira/browse/KAFKA-8403 >>>>> >>>>>>>>>>>>>>>> states. We >>>>>>>>>>>>> finally >>>>>>>>>>>>>>> ended >>>>>>>>>>>>>>>> in implementing the system in an email alerting >>>>>>>>>>>>>>>> system like this < >>>>>>>>>>>>> >>>> https://www.confluent.io/blog/kafka-streams-take-on-watermarks-an > d-t > riggers/ >>>>>>>>>>>>>>>> >>>>>>>> and had to collect the keys and windows of trouble by hand. >>>>>>>>>>>>>>>> I think these kinds of use cases would be much >>>>>>>>>>>>>>>> common. Should it be described in the KIP much >>>> more >>>>>>>>>>>>>>>> in detail? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Thanks, Dongjin >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Sat, Feb 15, 2020 at 4:43 AM John Roesler >>>>>>>>>>>>>>>> <vvcep...@apache.org> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>> Hi Dongjin, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Thanks for the KIP! >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Can you explain more about why the internal data >>>>>>>>>>>>>>>>> structures of >>>>>>>>>>>>>>> suppression >>>>>>>>>>>>>>>>> should be queriable? The motivation just says >>>>>>>>>>>>>>>>> that users might >>>>>>>>>>>>> want to >>>>>>>>>>>>>>> do >>>>>>>>>>>>>>>>> it, which seems like it could justify literally >>>>>>>>>>>>>>>>> anything :) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> One design point of Suppression is that if you >>>>>>>>>>>>>>>>> wanted to query the >>>>>>>>>>>>>>> “final >>>>>>>>>>>>>>>>> state”, you can Materialize the suppress itself >>>>>>>>>>>>>>>>> (which is why it >>>>>>>>>>>>> needs >>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>> variant); if you wanted to query the >>>>>>>>>>>>>>>>> “intermediate state”, you can materialize the >>>>>>>>>>>>>>>>> operator immediately before the suppress. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Example: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> ...count(Materialized.as(“intermediate”)) >>>>>>>>>>>>>>>>> .supress(untilWindowClosed(), >>>>>>>>>>>>>>>>> Materialized.as(“final”)) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I’m not sure what use case would require >>>>>>>>>>>>>>>>> actually fetching from the internal buffers. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Thanks, John >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Fri, Feb 14, 2020, at 07:55, Dongjin Lee >>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>> Hi devs, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> I'd like to reboot the discussion on KIP-508, >>>>>>>>>>>>>>>>>> which aims to >>>>>>>>>>>>> support a >>>>>>>>>>>>>>>>>> Materialized variant of KTable#suppress. It >>>>>>>>>>>>>>>>>> was initially >>>>>>>>>>>>> submitted >>>>>>>>>>>>>>>>> several >>>>>>>>>>>>>>>>>> months ago but closed by the inactivity. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - KIP: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>> >>>> https://cwiki.apache.org/confluence/display/KAFKA/KIP-508%3A+Make > +Su > ppression+State+Queriable >>>>>>>> - Jira: https://issues.apache.org/jira/browse/KAFKA-8403 >>>>>>>>>>>>>>>>>> All kinds of feedback will be greatly >>>>>>>>>>>>>>>>>> appreciated. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Best, Dongjin >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- *Dongjin Lee* >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> *A hitchhiker in the mathematical world.* >>>>>>>>>>>>>>>>>> *github: >>>>>>>>>>>>>>>>>> <http://goog_969573159/> >>>> github.com/dongjinleekr >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> > <https://github.com/dongjinleekr>linkedin: >>>>>>>>>>>>>>>>> kr.linkedin.com/in/dongjinleekr >>>>>>>>>>>>>>>>>> <https://kr.linkedin.com/in/dongjinleekr >>>>> speakerdeck: > speakerdeck.com/dongjin >>>>>>>>>>>>>>>>>> <https://speakerdeck.com/dongjin>* >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- *Dongjin Lee* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> *A hitchhiker in the mathematical world.* *github: >>>>>>>>>>>>>>>> <http://goog_969573159/>github.com/dongjinleekr >>>>>>>>>>>>>>>> <https://github.com/dongjinleekr>linkedin: >>>>>>>>>>>>>>> kr.linkedin.com/in/dongjinleekr >>>>>>>>>>>>>>>> <https://kr.linkedin.com/in/dongjinleekr >>>>> speakerdeck: > speakerdeck.com/dongjin >>>>>>>>>>>>>>>> <https://speakerdeck.com/dongjin>* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- *Dongjin Lee* >>>>>>>>>>>>>> >>>>>>>>>>>>>> *A hitchhiker in the mathematical world.* *github: >>>>>>>>>>>>>> <http://goog_969573159/>github.com/dongjinleekr >>>>>>>>>>>>>> <https://github.com/dongjinleekr>linkedin: >>>>>>>>>>>>> kr.linkedin.com/in/dongjinleekr >>>>>>>>>>>>>> <https://kr.linkedin.com/in/dongjinleekr>speakerdeck: >>>>>>>>>>>>> speakerdeck.com/dongjin >>>>>>>>>>>>>> <https://speakerdeck.com/dongjin>* >>>>>>>>>>>>>> >>>>>>>>>>>> -- *Dongjin Lee* >>>>>>>>>>>> >>>>>>>>>>>> *A hitchhiker in the mathematical world.* *github: >>>>>>>>>>>> <http://goog_969573159/>github.com/dongjinleekr >>>>>>>>>>>> <https://github.com/dongjinleekr>linkedin: >>>>>>>>>>>> kr.linkedin.com/in/dongjinleekr >>>>>>>>>>>> <https://kr.linkedin.com/in/dongjinleekr>speakerdeck: >>>>>>>>>>>> speakerdeck.com/dongjin <https://speakerdeck.com/dongjin >>>>> * >>>>>>>>>>>> >>>>>> >>>> >>>> >>> >>> >> >> -- >> *Dongjin Lee* >> >> *A hitchhiker in the mathematical world.* >> >> >> >> >> *github: <http://goog_969573159/>github.com/dongjinleekr >> <https://github.com/dongjinleekr>keybase: https://keybase.io/dongjinleekr >> <https://keybase.io/dongjinleekr>linkedin: kr.linkedin.com/in/dongjinleekr >> <https://kr.linkedin.com/in/dongjinleekr>speakerdeck: speakerdeck.com/dongjin >> <https://speakerdeck.com/dongjin>* >> > >
signature.asc
Description: OpenPGP digital signature