I am trying to use map-reduce on CouchBase Lite. I have documents and they are being channelised. All doucments what I want are coming to Couchbase Lite. But When I Try to run map-reduce on them I am getting the following error
com.couchbase.lite.CouchbaseLiteException: Error when calling map block of view 'calendar', Status: 593 (HTTP 500 Application callback block failed)
Below is my map reduce function
private View createView(Database database){
View calendarView = database.getView("calendar");
calendarView.setMap(new Mapper() {
#Override
public void map(Map<String, Object> document, Emitter emitter) {
emitter.emit((long) document.get("date"),(long) document.get("cost"));
}
},"2");
return calendarView;
}
and Below is the part of main where I am calling the view and querying over it
View calendarView = createView(database);
Query query = database.getView("calendar").createQuery();
query.setStartKey(1472467249448l);
query.setEndKey(1472553649449l);
QueryEnumerator result = null;
try {
result = query.run();
} catch (CouchbaseLiteException e) {
e.printStackTrace();
}
for (Iterator<QueryRow> it = result; it.hasNext(); ) {
QueryRow row = it.next();
Log.d(TAG, row.getValue().toString());
}
As borrrden said in a comment above, Application callback block failed means your map function threw an exception. Use a debugger to find out what it is.
A likely possibility is that one of the documents in your database does not have a date property. In that case your map function would be passing null to the first (key) parameter of emit, which is an invalid argument.
Related
I am new to completableFuture, what I am trying to do is I have this logic below in spring boot project which I am trying to convert it to the parallel processing approach using completableFuture.
#Transaction
void serviceMethod{
for(Object obj : objList) //objlist can have 10000 objects and its a multi level composite objects
{
//Get corresponding entity obj from the database, if not found throw user exception
//Process i.e. change some fields
}
}
In the above logic sinnce the method is annotated with #Transaction I am not calling JPA save explicitly to save the entity.
Now, I am trying to do parallel processing with the above logic.
#Transaction
void serviceMethod{
for(Object obj : objList) //objlist can have 10000 objects and its a multi level composite objects
{
//Get corresponding entity obj from the database, if not found throw user exception
CompletableFuture<Optional<Obj>> optionalObjFuture = CompletableFuture.supplyAsync( () -> {//get the object from repository})
CompletableFuture<Obj> objFuture = optionalObjFuture.thenApply( optionalObj -> {
if(obj.isPresent()){
return obj.get();
}
else{
throw user exception;
}
})
////Process i.e. change some fields
}
}
Now the question is
what is the approach I have to follow to break the for loop when there is an exception?
How to handle transaction in this scenario. Is there any way to handle transaction without the need to call saveAll on the processed objects stored in datastructure?
For (1), you could split those 10_000 calls into much smaller batches. For example:
public static void main(String[] args) throws Exception {
int innerIterations = 5;
ExecutorService service = Executors.newFixedThreadPool(innerIterations);
for(int i=0;i<10;++i) {
List<CompletableFuture<String>> list = new ArrayList<>();
int j = 0;
for(;j<innerIterations;++j) {
CompletableFuture<Optional<String>> cf = CompletableFuture.supplyAsync(() -> Optional.of("a"), service);
CompletableFuture<String> cf2 = cf.thenApplyAsync(x -> {
if(x.isPresent()) {
return x.get();
} else {
throw new RuntimeException("test");
}
}, Executors.newFixedThreadPool(2));
list.add(cf2);
}
i += j;
CompletableFuture<Void> all5 = CompletableFuture.allOf(list.toArray(new CompletableFuture[0]));
if(all5.isCompletedExceptionally()) {
// log exception, whatever
break;
} else {
List<String> set = list.stream().map(CompletableFuture::join).collect(Collectors.toList());
System.out.println(set);
}
}
}
This does a couple of things:
splits the initial 10 into two batches of 5.
call CompletableFuture::allOf on those 5 futures. Read the documentation to see that if at least one future fails from those 5, then all5 failed also.
if all5 did not fail (that is all5.isCompletedExceptionally() did not pass), call CompletableFuture::join to get all of the results. There will be no "joining" really, since the previous allOff already waited for them to be completed.
For the second question - you can't. You will need to create a transaction manually, but Spring makes it rather easy.
I've implemented an IMvxNavigationFacade for deep linking in my MvvmCross 5.6.x sample app. I've added logic in BuildViewModelRequest() to construct a MvxViewModelRequest with parameters passed in as MvxBundle.
if (url.StartsWith("http://www.rseg.net/rewards/"))
{
var parametersBundle = new MvxBundle();
var id = url.Substring(url.LastIndexOf('/') + 1);
parametersBundle.Data.Add("id", id);
return Task.FromResult(
new MvxViewModelRequest(typeof(RewardDetailViewModel),
parametersBundle, null));
}
However, this approach causes the old style Init() method to be called in the target ViewModel rather than the new typesafe Prepare() method.
public class RewardDetailViewModel :
MvxViewModel<RewardDetailViewModel.Parameteres>
{
...
public new void Init(string id)
{
if (!string.IsNullOrWhiteSpace(id))
{
if (int.TryParse(id, out _rewardId))
RaiseAllPropertiesChanged();
}
}
public override void Prepare(Parameteres parameter)
{
if (parameter != null)
{
_rewardId = parameter.RewardId;
RaiseAllPropertiesChanged();
}
}
}
Is there a way to construct a MvxViewModelRequest so that you pass in an instance of the parameter class for the target ViewModel causing the Prepare() method to be called?
The entire solution can be viewed on GitHub https://github.com/rsegtx/So.MvvmNav2
Thanks in advance!
After doing some research I found at lease one way to accomplish this.
Create a ViewModelInstanceRequest rather than a ViewModelRequest so that you can call ViewModelLoader.LoadViewModel passing in a parameters object; the ViewModelRequest only allows parameters to be passed using a MvxBundle. Make the following change to BuildViewModelRequest() on the NavigationFacade:
var request = new
MvxViewModelInstanceRequest(typeof(RewardDetailViewModel));
var parameters = new RewardDetailViewModel.Parameteres();
.... parse parameters and fill in parameters object
request.ViewModelInstance = ViewModelLoader.LoadViewModel(
request, parameters, null);
return Task.FromResult((MvxViewModelRequest)request);
Create your own IMvxNavigationService and add logic to inspect the object returned from the NavigationFacde and if it is a ViewModelInstanceRequest then use it as is rather than one previously creating.
var facadeRequest = await facade.BuildViewModelRequest(path,
paramDict).ConfigureAwait(false);
...
if (facadeRequest is MvxViewModelInstanceRequest)
request = facadeRequest as MvxViewModelInstanceRequest;
else
{
facadeRequest.ViewModelType = facadeRequest.ViewModelType;
if (facadeRequest.ParameterValues != null)
{
request.ParameterValues = facadeRequest.ParameterValues;
}
request.ViewModelInstance = ViewModelLoader.LoadViewModel(
request, null);
}
I've updated the original example on GitHub https://github.com/rsegtx/So.MvvmNav2.
Using Play Framework 2.1 with OpenID, if I cancel my authentication from the OpenID Provider, I get this exception :
[RuntimeException: play.api.libs.openid.Errors$AUTH_CANCEL$]
Here's my code :
Promise<UserInfo> userInfoPromise = OpenID.verifiedId();
UserInfo userInfo = userInfoPromise.get(); // Exception thrown here
But since it's a Runtime exception, I can't catch it with a try/catch so I'm stuck on how to avoid exception and returns something nicer than a server error to the client.
How can I do that?
A Promise is success biased, for all its operations, it assumes it actually contains a value and not an error.
You get the exception because you try to call get on a promise which contains an untransformed error.
What you want is to determine if the Promise is a success or an error, you can do that with pattern matching for instance.
try this code:
AsyncResult(
OpenID.verifiedId.extend1( _ match {
case Redeemed(info) => Ok(info.attributes.get("email").getOrElse("no email in valid response"))
case Thrown(throwable) => {
Logger.error("openid callback error",throwable)
Unauthorized
}
}
)
)
You may want to read more on future and promises, I recommend this excellent article :
http://danielwestheide.com/blog/2013/01/09/the-neophytes-guide-to-scala-part-8-welcome-to-the-future.html
edit :
checking the documentation (http://www.playframework.com/documentation/2.1.0/JavaOpenID) in java it seems you are supposed to catch and handle exceptions yourself.
In any case, you should catch exceptions and if one is thrown redirect
back the user to the login page with relevant information.
something like this should work :
public class Application extends Controller {
public static Result index() {
return ok("welcome");
}
public static Result auth() {
Map<String, String> attributes = new HashMap<String, String>();
attributes.put("email", "http://schema.openid.net/contact/email");
final Promise<String> stringPromise = OpenID.redirectURL("https://www.google.com/accounts/o8/id", "http://localhost:9000/auth/callback",attributes);
return redirect(stringPromise.get());
}
public static Result callback() {
try{
Promise<UserInfo> userInfoPromise = OpenID.verifiedId();
final UserInfo userInfo = userInfoPromise.get();
System.out.println("id:"+userInfo.id);
System.out.println("email:"+userInfo.attributes.get("email"));
return ok(userInfo.attributes.toString());
} catch (Throwable e) {
System.out.println(e.getMessage());
e.printStackTrace();
return unauthorized();
}
}
}
I created a WCF dataservice class to return query results to javascript client. Here's the pseudocode for my dataservice:
public class MyDataService : DataService<MyEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("MyGetMethod", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServicePRotocolVersion.V2;
}
[WebGet(UriTemplate = "{SomeID}"]
public IEnumerable<Models.Customer> MyGetMethod(int? someID)
{
if (someID == null) throw new DataServiceException("ID not specified");
MyEntities context = this.CurrentDataSource;
context.ContextOptions.LazyLoadingEnabled = false;
var q = Linq statement which queries for a collection of entities from context
IEnumerable<Models.Customer> result = q;
foreach (Models.Customer customer in result)
{
if (!customer.Contacts.IsLoaded)
customer.Contacts.Load();
}
return result;
}
}
The call from the client requests result in json. When I debug the get method in dataservice, result has the specific related data expanded in a property called WrappedRelatedEntities, but in the json returned to the client, for that related entity it said deferred.
What do I need to do to have those related entities returned to client? Thanks!
With WCF DS Service there's no way the server can force-expand a navigation property. It only works if the client asks for it. So change your service operation to return IQueryable and then the client needs to add $expand=NameOfThePropertyToExpand to the URL.
I spend most of my time in C# and am trying to figure out which is the best practice for handling an exception and cleanly return an error message from a called method back to the calling method.
For example, here is some ActiveDirectory authentication code. Please imagine this Method as part of a Class (and not just a standalone function.)
bool IsUserAuthenticated(string domain, string user, string pass, out errStr)
{
bool authentic = false;
try
{
// Instantiate Directory Entry object
DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, user, pass);
// Force connection over network to authenticate
object nativeObject = entry.NativeObject;
// No exception thrown? We must be good, then.
authentic = true;
}
catch (Exception e) { errStr = e.Message().ToString(); }
return authentic;
}
The advantages of doing it this way are a clear YES or NO that you can embed right in your If-Then-Else statement. The downside is that it also requires the person using the method to supply a string to get the Error back (if any.)
I guess I could overload this method with the same parameters minus the "out errStr", but ignoring the error seems like a bad idea since there can be many reasons for such a failure...
Alternatively, I could write a method that returns an Error String (instead of using "out errStr") in which a returned empty string means that the user authenticated fine.
string AuthenticateUser(string domain, string user, string pass)
{
string errStr = "";
try
{
// Instantiate Directory Entry object
DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, user, pass);
// Force connection over network to authenticate
object nativeObject = entry.NativeObject;
}
catch (Exception e) { errStr = e.Message().ToString(); }
return errStr;
}
But this seems like a "weak" way of doing things.
Or should I just make my method "void" and just not handle the exception so that it gets passed back to the calling function?
void AuthenticateUser(string domain, string user, string pass)
{
// Instantiate Directory Entry object
DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, user, pass);
// Force connection over network to authenticate
object nativeObject = entry.NativeObject;
}
This seems the most sane to me (for some reason). Yet at the same time, the only real advantage of wrapping those 2 lines over just typing those 2 lines everywhere I need to authenticate is that I don't need to include the "LDAP://" string. The downside with this way of doing it is that the user has to put this method in a try-catch block.
Thoughts?
Is there another way of doing this that I'm not thinking of?
There is no "one size fits all". If you return a flag, that makes it easy to use a method in if() and loops. Exceptions always need a lot of boiler plate code. If you just want a string which you can display to the user (say, in a web UI), returning the error string (or null for "no error") is good, too.
But most of the time, I throw an exception (and in Java a subclass of RuntimeException) because that allows me to return more than a single information about the error (like: Which file caused the error? Which line/column? What was I doing? Which field in a form should be marked as illegal? etc).
In your case, you can't handle the exception in your method, so you shouldn't catch it. Only catch it when you can do something about it.
In this example, I agree, you should let the exception flow through to the consumer. However, as an alternative to the approaches you highlighted, consider this approach.
You can use a response object to hold information coming out of a method run, for example:
public abstract class BaseResponse
{
public bool IsOk { get; protected set;}
public string Message { get; protected set; }
}
public class AuthenticationResponse: BaseResponse
{
public AuthenticationResponse(bool isOk): this(isOk, "") {}
public AuthenticationResponse(bool isOk, string message)
{
IsOk = isOk;
Message = message;
}
}
AuthenticationResponse IsUserAuthenticated(string domain, string user, string pass)
{
bool authentic = false;
string errStr;
try
{
// Instantiate Directory Entry object
DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, user, pass);
// Force connection over network to authenticate
object nativeObject = entry.NativeObject;
// No exception thrown? We must be good, then.
authentic = true;
}
catch (Exception e) { errStr = e.Message().ToString(); }
return new AuthenticationResponse(authentic, errStr);
}
Then to use it in your if statements:
AuthenticationResponse response;
if((response = IsUserAuthenticated("domain", "user", "pass")).IsOk)
{
// do successful activity
} else {
Console.WriteLine(response.Message)
}
The trick is the return value of an assignment operation is the value that was assigned. So, we can do the assignment and the valid check in the same line. If you didn't need to hold onto the result of the call, you could simply call the method and check the IsOk property.
if(IsUserAuthenticated("domain", "user", "pass").IsOk)
{
// do successful activity
}
Then you can build up your custom response object to return any combination of values from your method as you need.
Don't handle the exception or return a message of any kind. Let the consumer of your method take care of this.