Reactor CacheMono onCacheMissResume called when cache is present - reactive-programming

I want to use cachemono and created a test to evaluate. So I created 2 mono and concatenated. What I notice is that oncachemissresume is called for both mono, but on the second mono, cache is not written. Is there anything wrong with my test? I want to use oncachemissresume to populate the cache and the current test results does not help me.
AtomicReference<Context> storeRef = new AtomicReference<>(Context.empty());
String key = "myid";
Mono<Integer> cachedMonoFirst = CacheMono
.lookup(k -> Mono.justOrEmpty(storeRef.get().<Integer>getOrEmpty(k))
.map(integer -> {
log.error("first :: cache lookup result {}", integer);
return Signal.next(integer);
}),
key)
.onCacheMissResume(() -> {
log.info("first :: cache missed ");
return Mono.just(123);})
.andWriteWith((k, sig) -> {
log.info("first :: cache write");
return Mono.fromRunnable(() ->
storeRef.updateAndGet(ctx -> ctx.put(k, sig.get())));});
Mono<Integer> cachedMonoSecond = CacheMono
.lookup(k -> Mono.justOrEmpty(storeRef.get().<Integer>getOrEmpty(k))
.map(integer -> {
log.error("second :: cache lookup result {}", integer);
return Signal.next(integer);
}),
key)
.onCacheMissResume(() -> {
log.error("second :: cache missed");
return Mono.just(456);})
.andWriteWith((k, sig) -> {
log.info("second :: cache write");
return Mono.fromRunnable(() ->
storeRef.updateAndGet(ctx -> ctx.put(k, sig.get())));});
Flux<Integer> cacheFlux = cachedMonoFirst.concatWith(cachedMonoSecond);
StepVerifier
.create(cacheFlux)
.consumeNextWith(data -> {
assertThat(storeRef.get().<Integer>getOrEmpty(key)).get().isEqualTo(data);
log.info(" first :: from cache {} {}", data, storeRef.get().<Integer>getOrEmpty(key));
})
.consumeNextWith(data -> {
assertThat(storeRef.get().<Integer>getOrEmpty(key)).get().isEqualTo(data);
log.info(" second :: from cache {} {}", data, storeRef.get().<Integer>getOrEmpty(key));
})
.verifyComplete();
The logs are as follows
CacheTest - first :: cache missed
CacheTest - first :: cache write
CacheTest - first :: from cache 123 Optional[123]
CacheTest - second :: cache missed
CacheTest - second :: cache lookup result 123
CacheTest - second :: from cache 123 Optional[123]
why does second :: cache missed called before second :: cache lookup result 123 ?

wrap onCacheMissResume with Mono.defer like shown below
.onCacheMissResume(Mono.defer(() -> {
log.error("second :: cache missed");
return Mono.just(456);}))

Related

How do I convert a raw slice of bytes representing a PostgreSQL numeric column into a f64?

I'm querying an instance of PostgreSQL and selecting a sum of a decimal value:
db=# SELECT SUM(distance) AS total_distance FROM table_name WHERE deleted_at IS NULL;
total_distance
-----------------------
3808.0666666666666578
(1 row)
When I try to execute this query in Rust:
extern crate postgres;
use postgres::{Connection, TlsMode};
fn main() {
let conn = Connection::connect("postgresql://u:p#localhost:5432/db", TlsMode::None).unwrap();
let query = "SELECT SUM(distance) AS total_distance FROM table_name WHERE deleted_at IS NULL;";
for row in &conn.query(query, &[]).unwrap() {
let total_distance: f64 = row.get("total_distance");
println!("{}", total_distance);
}
}
Results in:
thread 'main' panicked at 'error retrieving column "total_distance": Error(Conversion(WrongType(Type(Numeric))))'
I've seen in various threads that the Numeric type isn't supported by the Postgres crate, so I've tried creating my own numeric type:
#[derive(Debug)]
struct Float64(f64);
impl FromSql for Float64 {
fn from_sql(ty: &Type, raw: &[u8]) -> Result<Float64, Box<Error + Sync + Send>> {
let bytes = raw.try_into().expect("failed!");
Ok(Float64(f64::from_be_bytes(bytes)))
}
fn from_sql_null(ty: &Type) -> Result<Float64, Box<Error + Sync + Send>> {
Ok(Float64(0.0))
}
fn from_sql_nullable(
ty: &Type,
raw: Option<&[u8]>,
) -> Result<Float64, Box<Error + Sync + Send>> {
match raw {
None => Ok(Float64(0.0)),
Some(value) => Float64::from_sql(ty, value),
}
}
fn accepts(ty: &Type) -> bool {
NUMERIC.eq(ty)
}
}
impl Display for Float64 {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_string())
}
}
But this still doesn't work as the raw bytes fail to unwrap:
thread 'main' panicked at 'failed!: TryFromSliceError(())', src/libcore/result.rs:1165:5
raw: &[u8] has the length of 18, which is why it can't unwrap. What would be the best way to convert an 18 byte slice to f64?

RxJava2, how to emit a list of all emits so far on each emit

I have a stream of objects emitted from an Observable.
Each time there is an emit I want to map it to a list of all emits so far,
I know I can do it by storing a global list and do it manualy, but I was wondering if there is an operator that does this out of the box.
a -> [a]
b -> [a,b]
c -> [a,b,c]
a -> [a,b,c,a]
d -> [a,b,c,a,d]
f -> [a,b,c,a,d,f]
b -> [a,b,c,a,d,f,b]
g -> [a,b,c,a,d,f,b,g]
when I use toList(). it only sends a single list once the stream completes.
EDIT 1:
here is the way my flow looks right now:
source.itemStream()
.doOnNext( item -> handleItem())
.subscribe()
and what I would prefer is more along the lines of:
source.itemStream()
.someOperator() // this will map to a stream of all items so far.
.doOnNext( item -> handleItem())
.subscribe()
or alternatively
source.itemStream()
.compose(x -> listBuildingFunction(x)) // this will map to a stream of all items so far.
.doOnNext( item -> handleItem())
.subscribe()
Collect the items into a list and emit a copy of that list:
Observable.defer(() -> {
List<Integer> seen = new LinkedList<>();
return Observable.range(1, 10)
.map(v -> {
seen.add(v);
return new ArrayList<>(seen);
});
})
.subscribe(System.out::println);
using akarnokd's Answer above I did the following: (in Kotlin)
private fun toPartialList(): ObservableTransformer<Item>, List<Item>> {
return ObservableTransformer { observable ->
Observable.defer {
val tempList = ArrayList<Item>()
observable.map { item ->
tempList.add(item)
return#map ArrayList(tempList)
}
}
}
}
and then used it in my stream:
source.itemStream()
.compose(toPartialList())
.doOnNext { handleItems(it) }
.subscribe()

Checking a list and timing out if all entries not found in RxJava/RxKotlin

I have a scenario where I have a function, scanForTargets, that returns an Observable of type FoundNumber. In FoundNumber I just need an ID field I can grab out of it. As each element comes back in the scanResults Observable, I want to check to see if the name field matches one of the names on a target list. If so, then I want to emit that. For example, if I am looking for numbers 1, and 2, and scanForTargets() emits back 1, 2, 3, and 4, then I want scanForValues to emit back only 1 and 2.
The caveat is that I only want to continue doing this until either:
1) A time period elapses (in which case I throw and error)
2) All items on the String list are found before the timeout.
What I have so far looks like this, but I cannot get it to work for me mostly due to the shortcut of stopping once/if all of the targets are found before the timeout.
fun scanForValues(targetList: List<String>): Observable<FoundNumber> {
val scanResult = scanForTargets()
return scanResult.doOnNext {scanResult -> Log.d(TAG, "Found potential target: " + scanResult.name) }
.filter(TargetPredicate(targetList)) //See if it's one of those we want
.timeout(5, TimeUnit.SECONDS) //Wait a max of 5 seconds to find all items
.doOnError { Log.w(TAG, "Failed to scan"}") }
.map{s->scanResult.name}
}
class TargetPredicate(private val targetList: List<String>) : Predicate<ScanResult> { override fun test(scanResult: ScanResult): Boolean {
if(scanResult == null) {
return false
}
return scanResult.name in targetList
}
}
How can I also add the check to stop if I find all of the items in the list? I can't just add another predicate right?
Thanks.
Update: As requested, here is some data to show what I mean.
Let's say that the scanForTargets() and supporting code looks like this:
var emittedList: List<String?> = listOf(null, "0", "1", "2", "3")
fun scanForTargets(): Observable<FoundNumber> = Observable
.intervalRange(0, emittedList.size.toLong(), 0, 1, TimeUnit.SECONDS)
.map { index -> FoundNumber(emittedList[index.toInt()]) }
data class FoundNumber(val targetId: String?)
Now if scanForValues was called with a list of 1 and 2, then it should emit back an Observable of 1 and then 2.
No, it is not as simple as adding another filter.
A possible solution is to use scan to remove items from a set containing your targets, and complete when the set becomes empty.
Example:
val targets = listOf("a", "b", "c")
fun scanForTarget(): Observable<String> = Observable.just("a", "b")
fun scanForValues(targets: List<String>): Completable {
val initial = targets.toMutableSet()
return scanForTarget()
.timeout(5, TimeUnit.SECONDS)
.scan(initial) { acc, next -> acc.remove(next); acc }
.filter { it.isEmpty() }
.singleOrError()
.toCompletable()
}
Note: a Completable is a special type of publisher that can only signal onComplete or onError.
Update: response to question update.
The new example in your question won't work, because null values are not allowed in RxJava2.
Assuming you fix that, the following solution may help you.
fun scanForValues(targets: List<String>): Observable<String> {
val accumulator: Pair<Set<String>, String?> = targets.toSet() to null
return scanForTarget()
.timeout(5, TimeUnit.SECONDS)
.scan(accumulator) { acc, next ->
val (set, previous) = acc
val item = if (next in set) next else null
(set - next) to item // return set and nullable item
}
.filter { it.second != null } // item not null
.take(initial.size) // limit to the number of items
.map { it.second } // unwrap the item from the pair
.map { FoundNumber(it) } // wrap in your class
}
Instead of using only the Set<String> as the accumulator, now we also add the item.
The item is nullable, this allows us to check if a given item was present or not.
Notice that no null values are passed through the observable flow. In this case null values are wrapped inside Pair<Set<String>, String?> which are never null themselves.

How to implement repeat untill (condition) loop in promela?

Which would be right approach to do :
repeat{
...
} until(<condition>)
in Promela ?
I have tried :
do::
//..
(condition) -> break;
od
and
do ::
//..
if::(condition) -> break;
else
fi;
od
Your first attempt is incorrect, because if <condition> is not true the process will simply block forever.
Your second attempt is functionally correct. Personally, I would prefer a minor variant to your solution which does not drop the true entry condition for executing the bulk code.
Given
repeat{
// bulk code
} until(<condition>)
you have the following options:
do:
do
:: true ->
// bulk code
if
:: <condition> ->
break;
:: else;
fi;
od;
or
do
:: true ->
// bulk code
if
:: ! <condition>;
:: else ->
break;
fi;
od;
goto:
L1:
// bulk code
if
:: <condition>;
:: else
-> goto L1;
fi;
or
L1:
// bulk code
if
:: ! <condition>
-> goto L1;
:: else;
fi;
unless (do not use!):
do
:: true ->
d_step {
// bulk code
}
od unless { <condition> };
Note that there are two catches with this approach:
it assumes that the value of <condition> is altered within // bulk code and not anywhere else in the code (e.g. by some other process)
depending on the content of // bulk code, it might not possible to use d_step at all.
Only in the case in which the instruction altering the evaluation of <condition> is precisely the last one inside // bulk code then one is allowed to drop d_step without affecting the semantics.
To see why this is the case, observe the behaviour of Spin on the following code example:
active proctype example()
{
int cc = 0;
do
:: true ->
printf("before %d\n", cc);
cc++;
printf("after %d\n", cc);
od unless { cc == 3 };
}
which has the following output:
~$ spin test.pml
before 0
after 1
before 1
after 2
before 2
1 process created
since cc++ alters the evaluation of cc == 3 but is not the last instruction of the code sequence, the statement after 3 is never printed on screen.
EDIT:
Of course one could also try another variant of code with the unless statement, e.g.
bool flag;
do
:: true ->
// bulk code
flag = true;
flag = false;
od unless { flag && <condition> };
This is obviously always correct, even in the general case, but it clogs the source code with additional variables that are not part of the original problem, so I would still discourage the use of unless to replace do/until.
Here is an example of how to use it:
active proctype example()
{
int cc = 0;
bool flag = false;
do
:: true ->
printf("before %d\n", cc);
cc++;
printf("after %d\n", cc);
flag = true;
flag = false;
od unless { flag && (cc == 3) };
}
and indeed it yields the correct output:
~$ spin test.pml
before 0
after 1
before 1
after 2
before 2
after 3
1 process created

Extracting values from a reversed linked list

Question:
You have two numbers represented by a linked list, where each node contains a single digit. The digits are stored in reverse order, such that the 1 's digit is at the head of the list. Write a function that adds the two numbers and returns the sum as a linked list.
An Example:
Input: (7-> 1 -> 6) + (5 -> 9 -> 2).
That is: 617 + 295.
Output: 2 -> 1 -> 9.
That is: 912.
In order to begin with this question, I first created a class that would define what a linked list:
Step 1: Defining the linked list
class Node: CustomStringConvertible{
var value: Int
var next: Node?
var description: String{
if next != nil {
return "\(value) -> \(next!)"
}
else{
return "\(value) -> \(next)"
}
}
init(value: Int) {
self.value = value
}
}
Step: 2 - Generated the linked list, from user input of integer values
func generateList (num: Int) -> Node {
var stringNum = Array(String(num).characters)
let head = Node.init(value:Int(String(stringNum.first!))!)
var current = head
for i in 1..<stringNum.count{
let num = Int(String(stringNum[i]))
current.next = Node.init(value: num!)
current = current.next!
}
return head
}
let list = generateList(num: 716)
// The following prints out: 7 -> 1 -> 6 -> nil
Then I proceeded over to reverse the linked list using following function.
Step 3: Reverse the linked list
func reverseLinkedList (head: Node?) -> Node?{
var current = head
var prev: Node?
var next: Node?
while current != nil {
next = current?.next
current?.next = prev
prev = current
current = next
}
return prev
}
let reversedList = reverseLinkedList(head: list)
// The following prints out is: 6 -> 1 -> 7 -> nil
Step 4: The idea behind this step is to extract the values on each of the nodes, cast them as a string and then concatenate them to a string variable and then lastly cast the string value into an Int and then use that Int value and eventually add them.
func getValuesFrom (head: Node?) -> Int {
var string = ""
var current = head
while current != nil {
var stringVal = String(describing: current?.value)
string += stringVal
current = current?.next
}
return Int(string)!
}
Here is where I am having a problem:
When I plug in the following into this function like so:
getValuesFrom(head: reversedList)
I get the following error:
fatal error: unexpectedly found nil while unwrapping an Optional value
And I can't seem to figure out why I having a problem and would really appreciate any sort of insight.
There is no need to convert back and forth between String and the linked list, except to print it for results. This is done simply like this:
class Node {
var value: Int
var next: Node?
// init and generator can be the same method
init(value: Int) {
// store ones place and divide by 10
self.value = value % 10
var nextValue = value / 10
// set up for loop
var currentNode = self
while nextValue > 0 {
// create a new Node
// store ones place and divide by 10
let next = Node(value: nextValue % 10)
nextValue /= 10
// make the new Node the next Node
currentNode.next = next
// set up for next iteration
currentNode = next
}
}
}
// make the list printable
extension Node: CustomStringConvertible {
var description: String{
if let next = next {
return "\(value) -> \(next)"
}
else {
return "\(value) -> nil"
}
}
}
Now you can do:
print(Node(value: 671)) // prints "7 -> 1 -> 6 -> nil"
There is also no need to reverse the lists, given your question.
To sum the lists you can do just as you've said, convert to an Int, add them, then generate a new list:
extension Node {
func toValue() -> Int {
var place = 10
var current = self
// add each value and multiply by the place value
// first is 1, second 10, third 100, etc.
var result = current.value
while let next = current.next {
result += next.value * place
place *= 10
current = next
}
return result
}
}
Then all you need is to overload the addition operator...
func +(lhs: Node, rhs: Node) -> Node {
return Node(value: lhs.toValue() + rhs.toValue())
}
and test...
let first = Node(value: 617)
let second = Node(value: 295)
print(first)
print(second)
print(first + second)
Result:
7 -> 1 -> 6 -> nil
5 -> 9 -> 2 -> nil
2 -> 1 -> 9 -> nil