Why I need to add some delay while making concurrent request in streaming gRPC? (Java) to get output - asynchronous

#Test
public void testType() throws InterruptedException {
Integer num = 15;
String name = "Sahil";
Float percentage = 96.7f;
DOB dob = DOB.newBuilder().setDay(20).setMonth(8).setYear(2022).build();
ArrayList<Object> objects = new ArrayList<>(Arrays.asList(num,name,percentage,dob));
TypeRequest.Builder builder = TypeRequest.newBuilder();
StreamObserver<TypeResponse> typeResponseStreamObserver = new StreamObserver<TypeResponse>() {
#Override
public void onNext(TypeResponse typeResponse) {
System.out.println(
"Type : " + typeResponse.getType()
);
}
#Override
public void onError(Throwable throwable) {
System.out.println("Error : "+throwable);
}
#Override
public void onCompleted() {
System.out.println("Finished all requests");
}
};
StreamObserver<TypeRequest> typeRequestStreamObserver = this.calculatorServiceStub.getType(typeResponseStreamObserver);
for(Object obj : objects){
if (obj instanceof Integer){
builder.setNum((Integer) obj);
typeRequestStreamObserver.onNext(builder.build());
} else if (obj instanceof String) {
builder.setName((String) obj);
typeRequestStreamObserver.onNext(builder.build());
} else if (obj instanceof Float) {
builder.setFNum((Float) obj);
typeRequestStreamObserver.onNext(builder.build());
} else if (obj instanceof DOB) {
builder.setDob((DOB) obj);
typeRequestStreamObserver.onNext(builder.build());
}
// --------------------------------------------
Thread.sleep(500);
// --------------------------------------------
}
typeRequestStreamObserver.onNext(builder.clearType().build());
typeRequestStreamObserver.onCompleted();
}
If I did not add any delay then the output console is just blank. Testing with tools like BloomRPC and Postman it works fine,
but for this I don't know why this is happening?
Any little help will be very helpful. I appreciate it.

Related

Circuit Breaker with gRPC

In a REST service adding a circuit breaker with hystrix, I could do the following:
#HystrixCommand(fallbackMethod = "getBackupResult")
#GetMapping(value = "/result")
public ResponseEntity<ResultDto> getResult(#RequestParam("request") String someRequest) {
ResultDto resultDto = service.parserRequest(someRequest);
return new ResponseEntity<>(resultDto, HttpStatus.OK);
}
public ResponseEntity<ResultDto> getBackupResult(#RequestParam("request") String someRequest) {
ResultDto resultDto = new ResultDto();
return new ResponseEntity<>(resultDto, HttpStatus.OK);
}
Is there something similar I can do for the gRPC call?
public void parseRequest(ParseRequest request, StreamObserver<ParseResponse> responseObserver) {
try {
ParseResponse parseResponse = service.parseRequest(request.getSomeRequest());
responseObserver.onNext(parseResponse);
responseObserver.onCompleted();
} catch (Exception e) {
logger.error("Failed to execute parse request.", e);
responseObserver.onError(new StatusException(Status.INTERNAL));
}
}
I solved my problem by implementing the circuit-breaker on my client. I used the sentinel library
To react on exceptions ratio for example I added this rule:
private static final String KEY = "callGRPC";
private void callGRPC(List<String> userAgents) {
initDegradeRule();
ManagedChannel channel = ManagedChannelBuilder.forAddress(grpcHost, grpcPort).usePlaintext()
.build();
for (String userAgent : userAgents) {
Entry entry = null;
try {
entry = SphU.entry(KEY);
UserAgentServiceGrpc.UserAgentServiceBlockingStub stub
= UserAgentServiceGrpc.newBlockingStub(channel);
UserAgentParseRequest request = UserAgentRequest.newBuilder().setUserAgent(userAgent).build();
UserAgentResponse userAgentResponse = stub.getUserAgentDetails(request);
} catch (BlockException e) {
logger.error("Circuit-breaker is on and the call has been blocked");
} catch (Throwable t) {
logger.error("Exception was thrown", t);
} finally {
if (entry != null) {
entry.exit();
}
}
}
channel.shutdown();
}
private void initDegradeRule() {
List<DegradeRule> rules = new ArrayList<DegradeRule>();
DegradeRule rule = new DegradeRule();
rule.setResource(KEY);
rule.setCount(0.5);
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
rule.setTimeWindow(60);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}

Unable to capture screenshot using ExtentReport version 4-- Selenium-Java

Unable to capture a screenshot using extent report 4(Selenium-Java)
Error msg is :-
FAILED CONFIGURATION: #AfterMethod tearDown([TestResult name=expediaTitleCheck status=FAILURE method=Expedia_TC.expediaTitleCheck()[pri:0, instance:com.extent.testcases.Expedia_TC#72b6cbcc] output={null}])
Code is as follows:-
public class Expedia_TC {
WebDriver driver;
Expedia exp;
ExtentHtmlReporter htmlReport;
ExtentReports extent;
ExtentTest test;
#BeforeTest
public void startBrowser() {
htmlReport = new ExtentHtmlReporter(System.getProperty("user.dir")+"/Reports/ExpediaReport.html");
htmlReport.config().setEncoding("utf-8");
htmlReport.config().setDocumentTitle("Expedia Automation Report");
htmlReport.config().setReportName("Functional Report");
htmlReport.config().setTimeStampFormat("EEEE,DD-MM-YYYY,hh:mm:ss");
htmlReport.config().setTheme(Theme.DARK);
extent = new ExtentReports();
extent.attachReporter(htmlReport);
extent.setSystemInfo("OS","Windows10");
extent.setSystemInfo("Environment","Production");
extent.setSystemInfo("Tester","Jayashree");
WebDriverManager.firefoxdriver().setup();
System.setProperty(FirefoxDriver.SystemProperty.DRIVER_USE_MARIONETTE, "true");
System.setProperty(FirefoxDriver.SystemProperty.BROWSER_LOGFILE,"/dev/null");
driver = new FirefoxDriver();
exp = new Expedia(driver);
driver.manage().window().maximize();
driver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
}
#Test
public void expediaTitleCheck() {
test = extent.createTest("Title Check Test...");
exp.checkPageTitle();
test.fail("This Test is Failed!");
}
#AfterMethod
public void tearDown(ITestResult result)throws IOException {
if(result.getStatus() == ITestResult.FAILURE) {
String methodName ="<b>"+result.getMethod().getMethodName()+" : "+"FAILED"+"</b>";
String errorMsg = "<b>"+"REASON: "+" "+result.getThrowable().getMessage()+"</b>";
String failureScreenshot = Expedia_TC.captureScreen(driver, methodName);
test.log(Status.FAIL,MarkupHelper.createLabel(methodName,ExtentColor.RED));
test.log(Status.FAIL,errorMsg);
try {
test.addScreenCaptureFromPath(failureScreenshot);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
#AfterTest
public void endReport() {
extent.flush();
driver.quit();
}

want to use updateMessage("...") in a Class that is not an Task

I want to use updateMessage("...") in a Class that is not an Task.
How can I solve this Problem?
Is it possible to give a Task Handle which can perform a updateMessage("...") to a Function?
import javafx.concurrent.Task;
public class TestTask extends Task<Void> {
private final static int COUNT = 1000;
#Override
protected Void call() {
doTaskStuff("Found ");
return null;
}
public void doTaskStuff(String s) {
for (int i = 0; i < COUNT; i++) {
System.out.println(i);
this.updateProgress(i, COUNT);
this.updateMessage(s + (i + 1) + "!");
Dummy.dummy(this, i);
try {
Thread.sleep(1);
} catch (InterruptedException interruptedException) {
}
}
}
}
class Dummy {
public static void dummy(TestTask testTask, int i) {
String s = "";
if (i == 0) {
s = "i == 0";
} else {
s = "i != 0";
}
testTask.updateMessage(s);// does not work
}
}
The issue here is the method being protected. Of course you could override the method and increase the visibility, but this would imho be a bad approach:
#Override
public void updateMessage(String message) {
super.updateMessage(message);
}
Note that the method sets a single message, therefore you could just return the value:
updateMessage(Dummy.dummy(i));
public static String dummy(int i) {
return (i == 0) ? "i == 0" : "i != 0";
}
For multiple updates you could also provide access to this kind of functionality using an interface:
Dummy.dummy(this::updateMessage, i);
public static void dummy(Consumer<String> updater, int i) {
updater.accept((i == 0) ? "i == 0" : "i != 0");
}

I'm trying to dispose of an object when the system is low on memory - is there a better way than this?

What I am doing currently is adding an item to the Cache and disposing of my object when that object is removed from the Cache. The logic being that it gets removed when memory consumption gets too high. I'm open to outher suggestions but I would like to avoid creating a thread than continually measures memory statistics if possible. Here is my code:
public class WebServiceCache : ConcurrentDictionary<string, WebServiceCacheObject>, IDisposable
{
private WebServiceCache()
{
if (HttpContext.Current != null && HttpContext.Current.Cache != null)
{
HttpContext.Current.Cache.Add("CacheTest", true, null, DateTime.Now.AddYears(1), System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.Low,
(key, obj, reason) => {
if (reason != System.Web.Caching.CacheItemRemovedReason.Removed)
{
WebServiceCache.Current.ClearCache(50);
}
});
}
}
private static WebServiceCache _current;
public static WebServiceCache Current
{
get
{
if (_current != null && _current.IsDisposed)
{
// Might as well clear it fully
_current = null;
}
if (_current == null)
{
_current = new WebServiceCache();
}
return _current;
}
}
public void ClearCache(short percentage)
{
try
{
if (percentage == 100)
{
this.Dispose();
return;
}
var oldest = _current.Min(c => c.Value.LastAccessed);
var newest = _current.Max(c => c.Value.LastAccessed);
var difference = (newest - oldest).TotalSeconds;
var deleteBefore = oldest.AddSeconds((difference / 100) * percentage);
// LINQ doesn't seem to work very well on concurrent dictionaries
//var toDelete = _current.Where(c => DateTime.Compare(c.Value.LastAccessed,deleteBefore) < 0);
var keys = _current.Keys.ToArray();
foreach (var key in keys)
{
if (DateTime.Compare(_current[key].LastAccessed, deleteBefore) < 0)
{
WebServiceCacheObject tmp;
_current.TryRemove(key, out tmp);
tmp = null;
}
}
keys = null;
}
catch
{
// If we throw an exception here then we are probably really low on memory
_current = null;
GC.Collect();
}
}
public bool IsDisposed { get; set; }
public void Dispose()
{
this.Clear();
HttpContext.Current.Cache.Remove("CacheTest");
this.IsDisposed = true;
}
}
In Global.asax
void context_Error(object sender, EventArgs e)
{
Exception ex = _context.Server.GetLastError();
if (ex.InnerException is OutOfMemoryException)
{
if (_NgageWebControls.classes.Caching.WebServiceCache.Current != null)
{
_NgageWebControls.classes.Caching.WebServiceCache.Current.ClearCache(100);
}
}
}
Thanks,
Joe
You can access the ASP.NET Cache from anywhere in your application as the static property:
HttpRuntime.Cache
You don't need to be in the context of a Request (i.e. don't need HttpContext.Current) to do this.
So you should be using it instead of rolling your own caching solution.

BlackBerry - Exception when sending SMS

The code below should send a text message to a mobile number. It currently fails to work properly.
When the program attempts a message, the following error is reported:
Blocking operation not permitted on event dispatch thread
I created a separate thread to execute the SMS code, but I am still observing the same exception.
What am I doing wrong?
class DummyFirst extends MainScreen {
private Bitmap background;
private VerticalFieldManager _container;
private VerticalFieldManager mainVerticalManager;
private HorizontalFieldManager horizontalFldManager;
private BackGroundThread _thread;
CustomControl buttonControl1;
public DummyFirst() {
super();
LabelField appTitle = new LabelField("Dummy App");
setTitle(appTitle);
background = Bitmap.getBitmapResource("HomeBack.png");
_container = new VerticalFieldManager(Manager.NO_VERTICAL_SCROLL
| Manager.NO_VERTICAL_SCROLLBAR) {
protected void paint(Graphics g) {
// Instead of these next two lines, draw your bitmap
int y = DummyFirst.this.getMainManager()
.getVerticalScroll();
g.clear();
g.drawBitmap(0, 0, background.getWidth(), background
.getHeight(), background, 0, 0);
super.paint(g);
}
protected void sublayout(int maxWidth, int maxHeight) {
int width = background.getWidth();
int height = background.getHeight();
super.sublayout(width, height);
setExtent(width, height);
}
};
mainVerticalManager = new VerticalFieldManager(
Manager.NO_VERTICAL_SCROLL |
Manager.NO_VERTICAL_SCROLLBAR) {
protected void sublayout(int maxWidth, int maxHeight) {
int width = background.getWidth();
int height = background.getHeight();
super.sublayout(width, height);
setExtent(width, height);
}
};
HorizontalFieldManager horizontalFldManager =
new HorizontalFieldManager(Manager.USE_ALL_WIDTH);
buttonControl1 = new CustomControl("Send", ButtonField.CONSUME_CLICK,
83, 15);
horizontalFldManager.add(buttonControl1);
this.setStatus(horizontalFldManager);
FieldListener listner = new FieldListener();
buttonControl1.setChangeListener(listner);
_container.add(mainVerticalManager);
this.add(_container);
}
class FieldListener implements FieldChangeListener {
public void fieldChanged(Field f, int context) {
if (f == buttonControl1) {
_thread = new BackGroundThread();
_thread.start();
}
}
}
private class BackGroundThread extends Thread {
public BackGroundThread() {
/*** initialize parameters in constructor *****/
}
public void run() {
// UiApplication.getUiApplication().invokeLater(new Runnable()
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
try {
MessageConnection msgConn =
(MessageConnection) Connector
.open("sms://:0");
Message msg = msgConn
.newMessage(
MessageConnection.TEXT_MESSAGE);
TextMessage txtMsg = (TextMessage) msg;
String msgAdr = "sms://+919861348735";
txtMsg.setAddress(msgAdr);
txtMsg.setPayloadText("Test Message");
// here exception is thrown
msgConn.send(txtMsg);
System.out.println("Sending" +
" SMS success !!!");
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
} // run
});
}
}
public boolean onClose() {
System.out.println("close event called, request to be" +
" in the backgroud....");
UiApplication.getUiApplication().requestBackground();
return true;
}
}
Dec 14, 2009 Stella answered their own question:
I resolved this issue by creating a separate thread and then not using Port etc.
Here it is:
SMSThread smsthread = new SMSThread("Some message",mobNumber);
smsthread.start();
class SMSThread extends Thread {
Thread myThread;
MessageConnection msgConn;
String message;
String mobilenumber;
public SMSThread( String textMsg, String mobileNumber ) {
message = textMsg;
mobilenumber = mobileNumber;
}
public void run() {
try {
msgConn = (MessageConnection) Connector.open("sms://+"+ mobilenumber);
TextMessage text = (TextMessage) msgConn.newMessage(MessageConnection.TEXT_MESSAGE);
text.setPayloadText(message);
msgConn.send(text);
msgConn.close();
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
}

Resources