Using Observable.interval to wait for remote data or timeout - java

I need to wait for a condition or timeout. I came up with the following approach, but there are too many things happening. How can i compress this.
import io.reactivex.Observable;
import java.util.concurrent.TimeUnit;
import io.reactivex.schedulers.Schedulers;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.ThreadLocalRandom;
public class Test{
public static void main(String[] args)throws InterruptedException{
AtomicBoolean toggle = new
java.util.concurrent.atomic.AtomicBoolean(true);
Observable.interval(0,50, TimeUnit.MILLISECONDS)
.takeWhile(l->l<(20000/50))
.takeWhile(l-> toggle.get())
.observeOn(Schedulers.io())
.map(l->{ return (l>ThreadLocalRandom.current()
.nextInt(5, 20 + 1))?true:false;})
// The above map will call a remote function to check for some condition
.observeOn(Schedulers.computation())
.filter(exist->exist)
//.takeWhile(exist->!exist)
.map(l->{toggle.set(false);return l;})
.map(l->{System.out.println("Called at "+l);return l;})
.blockingSubscribe();
}
}

Here is code. You can use firstElement to get the first item.
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
public class Q44234633 {
public static void main(String[] args) throws InterruptedException {
Observable.interval(50, TimeUnit.MILLISECONDS)
.takeWhile(l -> l < 400)
.observeOn(Schedulers.io())
.filter(l -> isConditionTrue(l))
.observeOn(Schedulers.computation())
.firstElement()
.doOnSuccess(System.out::println)
.isEmpty()
.filter(empty -> empty)
.doOnSuccess(b -> System.out.println("TimeOut"))
.blockingGet();
}
private static boolean isConditionTrue(long time) {
return time > ThreadLocalRandom.current().nextInt(5, 20 + 1);
}
}
There are also two tips for you.
You can use doOnNext rather than map if you actually don't map the value.
BooleanValue? true : false can be written BooleanValue directly.

Related

Block texture load only when placed, but not in inventory

I've read some other 'similar' questions but their problems is exactly the opposite. I've also read the docs but they won't provide anything useful to this problem.
When I /give myself the block, it shows a missing texture in my inventory as a item. But when I place it, its texture is shown in the world as a block.
Screenshot:
Main mod class:
package com.byethost8.code2828.mcmods.chemc;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.OreBlock;
import net.minecraft.block.material.Material;
import net.minecraft.block.material.MaterialColor;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item.Properties;
import net.minecraft.item.ItemGroup;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
#Mod(CheMC_.modid)
public class CheMC_ {
public static final String modid = "chemc";
public static OreBlock ore_lithium = (OreBlock) new OreBlock(
AbstractBlock.Properties
.create(Material.ROCK, MaterialColor.PINK_TERRACOTTA)
.harvestLevel(1)
.hardnessAndResistance(1, 1)
.setLightLevel(
light -> {
return 1;
}
)
)
.setRegistryName("chemc", "lithium_ore");
public static BlockItem i_ore_lithium = (BlockItem) new BlockItem(
ore_lithium,
new Properties().group(ItemGroup.BUILDING_BLOCKS)
)
.setRegistryName(ore_lithium.getRegistryName());
public static Block block_lithium = new Block(
AbstractBlock.Properties
.create(Material.IRON, MaterialColor.PINK_TERRACOTTA)
.harvestLevel(1)
.hardnessAndResistance(1.2F, 1)
.setLightLevel(
light -> {
return 1;
}
)
)
.setRegistryName("chemc", "lithium_block");
public static BlockItem i_block_lithium = (BlockItem) new BlockItem(
block_lithium,
new Properties().group(ItemGroup.BUILDING_BLOCKS)
)
.setRegistryName(block_lithium.getRegistryName());
public CheMC_() {
FMLJavaModLoadingContext
.get()
.getModEventBus()
.addListener(this::setup);
MinecraftForge.EVENT_BUS.register(this);
}
private void setup(final FMLCommonSetupEvent event) {}
// You can use EventBusSubscriber to automatically subscribe events on the
// contained class (this is subscribing to the MOD
// Event bus for receiving Registry Events)
#Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents {
#SubscribeEvent
public static void onBlocksRegistry(
final RegistryEvent.Register<Block> blockRegistryEvent
) {
// register a new block here
blockRegistryEvent
.getRegistry()
.registerAll(ore_lithium, block_lithium);
}
}
}
Some codes are removed to make the main problem clear.
Following texts only will say about Lithium Block, but same things apply for Lithium Ore.
Model File:
{
"parent": "block/cube_all",
"textures": {
"all": "chemc:block/lithium_block"
}
}
Folder structure of src/main/resources:
Blockstate:
{
"variants": {
"": [
{ "model": "chemc:block/lithium_block" }
]
}
}
I can't believe that I was stupid enough to register a Item and do nothing to assets/chemc/resources/models/item/ folder. See this for more. I have the exactly same problem as that OP.

Adding Potion Effect when Item is in hand Minecraft Forge 1.16.5

So Basically I have been searching the internet for a way to add potion effects while an item is being held. I have found many results but none really seem to be working. My main issue is that when I get to the adding potion effect it throws errors because I am trying to use a non-static to access an abstract. I tried the #Overide several times but it never seems to work. I still need to register in forge as that is how it updates but adding PlayerEntity does not work when I use #SubscribeEvent
package blitz.weapon.weaponmod;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.EffectInstance;
import net.minecraft.potion.Effects;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityDispatcher;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.world.NoteBlockEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.stream.Collectors;
// The value here should match an entry in the META-INF/mods.toml file
#Mod("weaponmod")
public class Weaponmod {
// Directly reference a log4j logger.
private static final Logger LOGGER = LogManager.getLogger();
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, "weaponmod");
public static final RegistryObject<Item> RAINBOW_SWORD = ITEMS.register("rainbow_sword", () ->
new Item(new Item.Properties()
.group(ItemGroup.COMBAT)
.maxStackSize(1)
.maxDamage(13)
));
public Weaponmod() {
// Register the setup method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
// Register the enqueueIMC method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
// Register the processIMC method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
// Register the doClientStuff method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);
// Register ourselves for server and other game events we are interested in
MinecraftForge.EVENT_BUS.register(this);
ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
}
#SubscribeEvent
public void onPlayerTick(TickEvent.PlayerTickEvent event) {
if (event.side.isServer() && event.phase == TickEvent.Phase.START) {
ItemStack stack = event.player.getHeldItemMainhand();
if (stack != null && stack.getItem() !=null) {
if (stack.getItem().equals("1 rainbow_sword")) {
return;
}
}
}
}
private void setup(final FMLCommonSetupEvent event) {
// some preinit code
LOGGER.info("HELLO FROM PREINIT");
LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName());
}
private void doClientStuff(final FMLClientSetupEvent event) {
// do something that can only be done on the client
LOGGER.info("Got game settings {}", event.getMinecraftSupplier().get().gameSettings);
}
private void enqueueIMC(final InterModEnqueueEvent event) {
// some example code to dispatch IMC to another mod
InterModComms.sendTo("weaponmod", "helloworld", () -> {
LOGGER.info("Hello world from the MDK");
return "Hello world";
});
}
private void processIMC(final InterModProcessEvent event) {
// some example code to receive and process InterModComms from other mods
LOGGER.info("Got IMC {}", event.getIMCStream().
map(m -> m.getMessageSupplier().get()).
collect(Collectors.toList()));
}
// You can use SubscribeEvent and let the Event Bus discover methods to call
#SubscribeEvent
public void onServerStarting(FMLServerStartingEvent event) {
// do something when the server starts
LOGGER.info("HELLO from server starting");
}
// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD
// Event bus for receiving Registry Events)
#Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents {
#SubscribeEvent
public static void onBlocksRegistry(final RegistryEvent.Register<Block> blockRegistryEvent) {
// register a new block here
LOGGER.info("HELLO from Register Block");
}
}
}
That is my code for basically my whole mod, can anyone give me any pointers? (Sorry for any mistakes this is my first post)

Mono retry with backoff not getting called for few elements in stream

There are stream of integers that I am trying to process. Incase of an exception I want to retry with backoff and at the same time backpressure will also be applied on the stream. I see that for few elements retry is not getting called.
To reproduce execute the below code and you should see code will be waiting indefinitely because queue becomes full coz for few elements doFinally is not called. In this case we should see count as 2000 but it will be less.
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import reactor.util.retry.Retry;
import java.time.Duration;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class MonoRetryTest {
private static final Logger logger = LoggerFactory.getLogger(MonoRetryTest.class);
private static BlockingQueue blockingQueue = new LinkedBlockingDeque(30);
private static final List values = Collections.synchronizedList(new LinkedList<Integer>());
#Test(timeout = 30000)
public void testMonoRetryWithBackOff() {
Flux.range(0,2000)
.publishOn(Schedulers.parallel())
.flatMap(e -> monoUtil(e))
.blockLast();
int processedValues = values.size();
Assert.assertTrue("Signal not recieved for all elements", 2000 == processedValues);
}
private static Mono monoUtil(int val) {
return Mono.just(1)
.flatMap(e -> {
try {
blockingQueue.put(val);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
return serviceCall(Mono.just(val));
})
.doFinally(e -> {
blockingQueue.remove(val);
values.add(val);
logger.info("Finally Called "+ val);
});
}
private static Mono serviceCall(Mono<Integer> responseMono) {
return responseMono
.map(response -> test(response))
.retryWhen(Retry.backoff(3, Duration.ofMillis(10)))
.onErrorReturn("Failed");
}
private static String test(Integer value) {
if(value%5 == 0) throw new RuntimeException("Runtime Exception");
return "Success";
}
}

requireThat() and requireSingleCommand() are undefined

I am new to Corda and started with the provided tutorials.
In two different tutorials I ran into the same problem. The functions requireThat() and requireSingleCommand() are undefined.
Below you see my code from the "HelloWorld! Pt. 2" tutorial.
The requireThat() function produces the following error:
The method requireThat((<no type> require) -> {}) is undefined for the type SignTxFlow Java(67108964)
Although, the requireThat() function is part of the net.corda.core.contracts package which is included in the code.
Thank you for your help!
package com.template.flows;
import com.template.states.IOUState;
import co.paralleluniverse.fibers.Suspendable;
import net.corda.core.contracts.ContractState;
import net.corda.core.crypto.SecureHash;
import net.corda.core.flows.FlowException;
import net.corda.core.flows.FlowLogic;
import net.corda.core.flows.FlowSession;
import net.corda.core.flows.InitiatedBy;
import net.corda.core.flows.ReceiveFinalityFlow;
import net.corda.core.flows.SignTransactionFlow;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.contracts.*;
import net.corda.core.flows.*;
import net.corda.core.contracts.Command;
import net.corda.core.transactions.*;
import net.corda.core.utilities.ProgressTracker;
// ******************
// * Responder flow *
// ******************
#InitiatedBy(IOUFlow.class)
public class IOUFlowResponder extends FlowLogic<Void> {
private FlowSession otherPartySession;
public IOUFlowResponder(FlowSession otherPartySession) {
this.otherPartySession = otherPartySession;
}
#Suspendable
#Override
public Void call() throws FlowException {
class SignTxFlow extends SignTransactionFlow {
private SignTxFlow(FlowSession otherPartySession) {
super(otherPartySession);
}
#Override
protected void checkTransaction(SignedTransaction stx) {
requireThat(require -> {
ContractState output = stx.getTx().getOutputs().get(0).getData();
require.using("this must be an IOU transaction. ", output instanceof IOUState);
IOUState iou = (IOUState) output;
require.using("The IOU's value can't be too high.", iou.getValue() < 100);
return null;
});
}
}
SecureHash expectedTxId = subFlow(new SignTxFlow(otherPartySession)).getId();
subFlow(new ReceiveFinalityFlow(otherPartySession, expectedTxId));
return null;
}
}
The problem is solved, if the package
import static net.corda.core.contracts.ContractsDSL.requireThat;
is implemented at the top.

Java SchedulerExecutor

Recently I wrote code that had to limit request throughput. I used ScheduleExecutorService.scheduleAtFixedRate and I believed that it should do the work (It did!) but I wrote some test to check time of scheduled task and i was amazed. First few tasks weren't scheduled as javadoc explain with n*period. Can anyone explain me what am I missing?
If it work that way then why it is not mentioned in javadoc? And then question is how exactly scheduler work?
I would like to avoid looking into sources:)
Example:
import java.time.Duration;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ExecutorTest {
Executor executor;
ScheduledExecutorService schedulingExecutor;
BlockingQueue<LocalTime> times;
public static void main(String[] args) throws InterruptedException {
new ExecutorTest().start();
}
public ExecutorTest() {
schedulingExecutor = Executors.newScheduledThreadPool(1);
executor = Executors.newCachedThreadPool();
times = new LinkedBlockingQueue<>();
}
public void start() throws InterruptedException {
schedulingExecutor.scheduleAtFixedRate(this::executeTask, 0, 50, TimeUnit.MILLISECONDS);
LocalTime nextEvaluatedTime = times.take();
LocalTime time = nextEvaluatedTime;
while (true) {
System.out.println(String.format(String.join(" ", "recorded time: %d", "calculated proper time: %d", "diff: %d"),
time.toNanoOfDay(),
nextEvaluatedTime.toNanoOfDay(),
Duration.between(nextEvaluatedTime, time).toNanos()));
nextEvaluatedTime = time.plus(50, ChronoUnit.MILLIS);
time = times.take();
}
}
private void executeTask() {
executor.execute(() -> {
times.add(LocalTime.now());
});
}
}
If you run this program you could see that few first time wasn't recorded as expected. Why?

Categories

Resources