I have an MVC application in which I have to update the view with the current value of a stream.
In the model I have this method:
public Observable<Integer> getStreamInstance(){
if(stream == null){
this.stream = Observable.create((Subscriber<? super Integer> subscriber) -> {
new HeartbeatStream(frequence,subscriber).start();
});
}
return stream;
}
which I use in the controller to get the stream. Then, in the controller I have these two methods:
public void start(){
this.sb = stream.subscribe((Integer v) -> {
view.updateCurrValue(v);
});
}
public void stop(){
this.sb.unsubscribe();
}
With the start method I simply update a label in the view with the current value.
This works fine until I try to stop the updating with the unsubscribing; infact, when I press the button "stop" in the view, the label keeps updating with the current value and, if I press "start" again, the label shows the values from two different streams, the one that I first created with the first "start" and the second that seems has been created with the second pressing of "start".
Where am I wrong?
EDIT:
public class HeartbeatStream extends Thread{
private Subscriber<? super Integer> subscriber;
private int frequence;
private HeartbeatSensor sensor;
public HeartbeatStream(int freq, Subscriber<? super Integer> subscriber){
this.frequence = freq;
this.subscriber = subscriber;
sensor = new HeartbeatSensor();
}
public void run(){
while(true){
try {
subscriber.onNext(sensor.getCurrentValue());
Thread.sleep(frequence);
} catch (Exception e) {
subscriber.onError(e);
}
}
}
This is the HeartbeatStream class. HeartbeatSensor is a class that periodically generates a value that simulates the heartbeat frequence.
I'm guessing you tried to periodically signal some event that triggers the screen update. There is an operator for that:
Observable<Long> timer = Observable.interval(period, TimeUnit.MILLISECONDS,
AndroidSchedulers.mainThread());
SerialSubscription serial = new SerialSubscription();
public void start() {
serial.set(timer.subscribe(v -> view.updateCurrValue(v)));
}
public void stop() {
serial.set(Subscriptions.unsubscribed());
}
public void onDestroy() {
serial.unsubscribe();
}
Observable by design unsubscribe your observer once that all items are emitted and onComplete callback is invoked.
Look this example https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/creating/ObservableSubscription.java
I guess you're not handling the unsubscribe - although I can't see what's going on in your HeartbeatStream class.
If you're creating an Observable with Observable.create then you need to handle unsubscribing explicitly with subscriber.isUnsubscribed().
Where possible use some of the utility methods to create an Observable - they handle this all for you eg Observable.just() or Observable.from().
If this doesn't help, please post your HeartbeatStream class.
See the the docs for more details:
https://github.com/ReactiveX/RxJava/wiki/Creating-Observables
https://github.com/ReactiveX/RxJava/wiki/Async-Operators
Related
When I click on an AjaxLink, I would like to have a validation via JavaScript on the client side first (because the LocalStorage is queried) and then depending on the result, further JavaScript calls are made. How can i achieve this?
In a pseudo code it would look like this:
new AjaxLink<>("myId", myModel) {
#Override
public void onClick(AjaxRequestTarget target) {
boolean isCounterValid = target.appendJavaScript(checkCounter()); // i know that this is not possible, therefore pseudo code
if(isCounterValid) {
target.appendJavaScript(someOtherJavaScript());
}
else {
target.appendJavaScript(anotherJavaScript());
}
}
private String checkCounter() {
return "var count = window.localStorage.getItem('myCounter'); return count !== 1;";
}
private String someOtherJavaScript() {
return "change something";
}
private String anotherJavaScript() {
return "change other thing";
}
};
You need to send extra request parameters with the Ajax call when the link is clicked. For that you should override updateAjaxAttributes(AjaxRequestAttributes attributes) method of AjaxLink:
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
{
attributes.getDynamicExtraParameters().add("var count = window.localStorage.getItem('myCounter'); return [{\"name\":\"count\", \"value\": count}]");
}
This way inside AjaxLink#onClick() you can read the count via:
int count = getRequest().getRequestParameters().getParameterValue("count").toInt();
AJAX components and behaviors can customize AJAX attributes overriding updateAjaxAttributes and using a custom implementation of AjaxCallListener which exposes different method to hook into the AJAX request cycle. In you case you could use AjaxCallListener#getBeforeSendHandler.
For a full introduction to this topic (with examples) see user guide:
https://ci.apache.org/projects/wicket/guide/8.x/single.html#_ajax_request_attributes_and_call_listeners
I have a table and a button and I want to emit an event ItemsSelected with the selected items of the table when the button is clicked.
The button should not know the table and it should remain only as a stream of clicks.
So this solution is discarded:
final ETable table = ...
PublishSubject<ItemSelected> selected = PublishSubject.create();
button.addSelectionListener(new SelectionListener(){
#Override
public void widgetSelected(SelectionEvent e) {
for (TableItem item : table.getSelection()) {
selected.onNext(new ItemSelected(item));
}
}
});
I would prefer a way to compose the click stream of the button with the item selection stream of the table in order to keep loose coupling between this two elements.
Because the table allows multiple selection I must first scan the items selected in order to emit an event with all the items. Something like:
public static class ItemsSelected<T> {
final List<T> items = new ArrayList<T>();
}
public abstract static class ItemSelection<T> {
public abstract void apply(ItemsSelected<T> selection);
}
public static class ItemUnselected<T> extends ItemSelection<T> {
final T item;
public ItemUnselected(T item) {
this.item = item;
}
public void apply(ItemsSelected<T> selection) {
selection.items.remove(item);
}
}
public static class ItemSelected<T> extends ItemSelection<T> {
final T item;
public ItemSelected(T item) {
this.item = item;
}
public void apply(ItemsSelected<T> selection) {
selection.items.add(item);
}
}
public static class ObservableTable<T> extends Table {
private PublishSubject<ItemSelection<T>> clicks = PublishSubject.create();
public Observable<ItemsSelected<T>> selection = clicks.scan(new ItemsSelected<T>(),
new Func2<ItemsSelected<T>, ItemSelection<T>, ItemsSelected<T>>() {
#Override
public ItemsSelected<T> call(ItemsSelected<T> t1, ItemSelection<T> t2) {
// breaking events immutability
t2.apply(t1);
return t1;
}
});
public ObservableTable(Composite parent, int style) {
super(parent, style);
this.addSelectionListener(new SelectionListener() {
#SuppressWarnings("unchecked")
#Override
public void widgetSelected(SelectionEvent e) {
if (((TableItem) e.item).getChecked())
clicks.onNext(new ItemSelected<T>((T) e.item.getData()));
else
clicks.onNext(new ItemUnselected<T>((T) e.item.getData()));
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
}
Then, I must combine the table.selection stream with the button.clicks stream in a selectionForAction stream. The idea is that when a ButtonClick is emitted, an SelectionForAction will be emitted if and only if an ItemSelected was previously emitted.
-------S1--U1-----S2---S3--------- table.clicks
(scan)
-------(1)--()---(2)---(2,3)------ table.selection
----O----------O-------------O---- button.clicks
(?)
-----------------------------(2,3) selectionForAction
So, wich operation should I use?
Zip: It doesn't work because if I click the button and later select an item, it should not do nothing, but with zip it will emit an event.
Join: I end up with a "solution" using join but it doesn't seem to be a good one. Somethinkg like:
table.selection.join(button.clicks, new Func1<ItemsSelected,Observable<Long>>() {
#Override
public Observable<Long> call(ItemsSelected t) {
// it doesn't seem a good idea
return Observable.timer(1, TimeUnit.DAYS);
}
}, new Func1<ClickEvent, Observable<Long>>() {
#Override
public Observable<Long> call(ClickEvent t) {
// this makes the ClickEvent be dropped if there is no previous ItemsSelected event emitted
return Observable.timer(1, TimeUnit.MILLISECONDS);
}
}, new Func2<ItemsSelected, ClickEvent, SelectionForAction>() {
#Override
public SelectionForActioncall(ItemsSelected t1, ClickEvent t2) {
return new SelectionForAction(t1.items);
}
});
Any idea?
I've found the operator that I needed to achieve the join behaviour with a very large time unit (DAYS in the example) and a very small one (MILLISECONDS).
With a variant of sample that takes another Observable as the sampler I could emit an event A only after an event of B would be emitted.
In my example the click acts as the sampler and the stream selection emits the events that I'm interested in. (This also requires to ignore the last event that is being emitted when the stream completes).
Another possible solution will be use the buffer(boundary):
The clicks stream would act as the boundary and I could avoid the scan operator because the list of items selected is created by the buffer operator. However with this solution I would not be considering unselection.
So, with sample I've achieved my original goal, however, I'm not happy with the way I handle items unselection and the final list of items selected.
In this case I need to maintain the state of the items selected in order to perform some operation on all of them when a ClickEvent occurs.
I could subscribe to the items selection/unselection and maintain a List of the items selected but then I'll have lost the possibility of compose the clicks observable with the selection observable.
With scan I maintain state and also keep the composability of observables, but representing the list of current selection as an event seems a little forced, in fact this represents a new issue: if I select x items and then click the button, an event with the selection is being emitted as expected, but if neither the items are unselected nor a new one is selected and then click again the button, nothing happens. So, it seems that selection doesn't fit as an event.
I've a CellTable to which I attach a click handler(via addDomHandler). Then I've added a custom cell which handles onBrowserEvent(...).
I'd like to stop the event to propagate in the cell's onBrowserEvent so that the table handler is not invoked anymore. Is this possible?
table = new CellTable();
table.addDomHandler(new ClickHandler() {
#Override
public void onClick(final ClickEvent pEvent) {
Trace.info("this shouldn't trigger");
}
}, ClickEvent.getType());
table.addColumn(new IdentityColumn<MyVO>(new MyCell()));
class MyCell extends AbstractCell<MyVO> {
#Override
public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context pContext, Element pParent,
Handle<DnSuggestionDetailsVO> pValue, NativeEvent pEvent,
ValueUpdater<Handle<DnSuggestionDetailsVO>> pValueUpdater) {
Trace.info("cell onBrowserEvent handled, propagation should stop here!");
pEvent.stopPropagation();
}
}
Thank you!
It's easier to cancel an event before it reaches the cell:
table.addCellPreviewHandler(new Handler<Item>() {
#Override
public void onCellPreview(CellPreviewEvent<Item> event) {
//do something
event.setCancelled(true);
}
});
Note that CellPreviewHandler already monitors all events within a table. You can use it for your ClickEvent as well (with finer control like which column is clicked) instead of adding a ClickHandler to the entire table.
Instead of checking every frame through the Update method, is there any event driven method to check if the value of an Enumerator as changed?
like:
public enum States{StateA, StateB,StateC};
States state;
void OnStateChanged(){
//do something..
}
Appreciate it.
You should use properties:
public enum States{StateA, StateB,StateC}
private States _state; //this holds the actual value
public States State { //this is public and accessible, and should be used to change "State"
get{
return _state;
}
set{
_state = value;
Debug.Log("Enum just got changed to: " + _state);
}
}
I want to re-write a method that has way too many nested if statements.
I came up with this approach and wanted your opinions:
public void MyMethod()
{
bool hasFailed = false;
try
{
GetNewOrders(out hasFailed);
if(!hasFailed)
CheckInventory(out hasFailed);
if(!hasFailed)
PreOrder(out hasFailed);
// etc
}
catch(Exception ex)
{
}
finally
{
if(hasFailed)
{
// do something
}
}
}
I've done stuff similar to that, but without the exception handling:
BOOL ok = CallSomeFunction();
if( ok ) ok = CallSomeOtherFunction();
if( ok ) ok = CallYetAnotherFunction();
if( ok ) ok = WowThatsALotOfFunctions();
if( !ok ) {
// handle failure
}
Or if you want to be clever:
BOOL ok = CallSomeFunction();
ok &= CallSomeOtherFunction();
ok &= CallYetAnotherFunction();
...
If you are using exceptions anyway, why do you need the hasFailed variable?
Not really. Your methods should raise an exception in case of an error to be caught by your "catch" block.
As far as I can see this is an example of cascade steps where second and third one will be executed if first and first and second are valid, i.e. return hasFailed==false.
This code can be made much more elegant using Template Method and Decorator design pattern.
You need one interface, concrete implementation, abstract class and several subclasses of the abstract class.
public interface Validator {
public boolean isValid();
}
public class GetNewOrders implements Validator {
public boolean isValid() {
// same code as your GetNewOrders method
}
}
public abstract class AbstractValidator implements Validator {
private final Validator validator;
public AbstractValidator(Validator validator) {
this.validator = validator;
}
protected boolean predicate();
protected boolean isInvalid();
public final boolean isValid() {
if (!this.validator.isValid() && predicate() && isInvalid())
return false;
return true;
}
}
public class CheckInventory extends AbstractValidator {
public CheckInventory(Validator validator) {
super(validator);
}
#Override
public boolean predicate() {
return true;
}
#Override
public boolean isInvalid() {
// same code as your CheckInventory method
}
}
public class PreOrder extends AbstractValidator {
public CheckInventory(Validator validator) {
super(validator);
}
#Override
public boolean predicate() {
return true;
}
#Override
public boolean isInvalid() {
// same code as your PreOrder method
}
}
Now your method can look much more elegant:
public void MyMethod() {
bool success = false;
try {
Validator validator = new GetNewOrders();
validator = new CheckInventory(validator);
validator = new PreOrder(validator);
success = validator.isValid();
} finally {
if (!success) {
// do something
}
}
}
Validator object can be created in one line, but I prefer this style since it makes obvious the order of validation. Creating new validation link in the chain is matter of subclassing AbstractValidator class and implementation of predicate and isInvalid methods.
Without commenting on the try/catch stuff since I really don't know what is going on there, I would change it so the called methods return true/false for success and then just check them depending on the boolean short-circuiting to avoid calling later methods if the preceding method failed.
public void MyMethod()
{
bool success = false;
try
{
success = GetNewOrders()
&& CheckInventory()
&& PreOrder();
// etc
}
catch(Exception ex) { }
finally
{
if(!success)
{
}
}
}
This doesn't really look good to me. The use of the hasFailed variable is really not nice. if GetNewOrders fails with an exception, you for instance end up inside the catch block with hasFailed = false !
Opposed to other answers here I believe there MAY be legitimate uses for boolean "hasFailed" that are not exceptional. But I really don't think you should mix such a condition into your exception handler.
I know I'll probably duplicate a few posts: What's wrong with else? You could also use lazy evaluation (a() && b()) to link methods - but that relies on status being given as return value, which is more readable anyhow IMHO.
I don't agree with posters that you should raise an exception, because exceptions should be raised if program faults occur or the program enters an exceptional state because of operations. Exceptions are not business logic.
I would do it like this:
public void MyMethod()
{
bool success = false;
try
{
GetNewOrders(); // throw GetNewOrdersFailedException
CheckInventory(); // throw CheckInventoryFailedException
PreOrder(); // throw PreOrderFailedException
success = true;
}
catch( GetNewOrdersFailedException e)
{
// Fix it or rollback
}
catch( CheckInventoryFailedException e)
{
// Fix it or rollback
}
catch( PreOrderFailedException e)
{
// Fix it or rollback
}
finally
{
//release resources;
}
}
Extending an exception is rather trivial,
public NewExecption : BaseExceptionType {}
Well, I don't like code that appears to get a list of orders and then process them, and then stop processing them when an error occurs, when surely it should skip that order and move to the next? The only thing to completely fail on is when the database (source of orders, destination of preorders) dies. I think that the entire logic is a bit funky really, but maybe that's because I don't have experience in the language you are using.
try {
// Get all of the orders here
// Either in bulk, or just a list of the new order ids that you'll call the DB
// each time for, i'll use the former for clarity.
List<Order> orders = getNewOrders();
// If no new orders, we will cry a little and look for a new job
if (orders != null && orders.size() > 0) {
for (Order o : orders) {
try {
for (OrderItem i : o.getOrderItems()) {
if (checkInventory(i)) {
// Reserve that item for this order
preOrder(o, i);
} else {
// Out of stock, call the magic out of stock function
failOrderItem(o, i);
}
}
} catch (OrderProcessingException ope) {
// log error and flag this order as requiring attention and
// other things relating to order processing errors that aren't database related
}
}
} else {
shedTears();
}
} catch (SQLException e) {
// Database Error, log and flag to developers for investigation
}
Your new approach is not that bad for a simple set of instructions, but what happens when additional steps are added? Do you / would you ever require transactional behavior? (What if PreOrder fails? or If the next step after PreOrder fails?)
Looking forward, I would use the command pattern:
http://en.wikipedia.org/wiki/Command_pattern
...and encapsulate each action as a concrete command implementing Execute() and Undo().
Then it's just a matter of creating a queue of commands and looping until failure or an empty queue. If any step fails, then simply stop and execute Undo() in order on the previous commands. Easy.
Chris solution is the most correct. But I think you should not do more than you need. Solution should be extandable and that's enough.
Change value of a parameter is a bad practice.
Never use empty generic catch statement, at least add a comment why you do so.
Make the methods throw exception and handle them where it is appropriate to do so.
So now it is much more elegant :)
public void MyMethod()
{
try
{
GetNewOrders();
CheckInventory();
PreOrder();
// etc
}
finally
{
// do something
}
}