Retrieving the latest emails with MailCore2 - ios

I'm loading my latest emails and I'm saving the latest UID because later if the user reload the list of emails I want to get all the emails from that UID to now... for this, I'm using
UInt64 start = lUid;
UInt64 end = UINT64_MAX;
MCOIMAPMessagesRequestKind requestKind = MCOIMAPMessagesRequestKindHeaders;
MCOIndexSet *uids = [MCOIndexSet indexSetWithRange:MCORangeMake(start, end)];
MCOIMAPFetchMessagesOperation *fetchOperation = [imapSession fetchMessagesOperationWithFolder:#"INBOX"
requestKind:requestKind
uids:uids];
this action always return the results but I'm getting the latest email... So I tried to make
UInt64 start = lUid + 1;
but it is exactly the same.
EDIT
I'm looking the logger and the last UID is 34038 so when i made the call the start parameter was 34039... so why im getting the email with id 34038?
2015-01-20 18:33:06.852 App[25022:730644] mailcore - IMAP: 8 UID FETCH 34039:* (UID ENVELOPE BODY.PEEK[HEADER.FIELDS (References)])
Anyone know whats going on?
EDIT 2:
So this is my code
UInt64 start = lUid + 1;
UInt64 end = UINT64_MAX;
MCOIMAPMessagesRequestKind requestKind = MCOIMAPMessagesRequestKindHeaders;
MCOIndexSet *uids = [MCOIndexSet indexSetWithRange:MCORangeMake(start, end)];
MCOIMAPFetchMessagesOperation *fetchOperation = [imapSession fetchMessagesOperationWithFolder:#"INBOX"
requestKind:requestKind
uids:uids];
void(^fetchHandler)(NSError *, NSArray *, MCOIndexSet *) = ^(NSError *error, NSArray *fetchedMessages, MCOIndexSet *vanishedMessages) {
if( error ) {
completionHandler(UIBackgroundFetchResultFailed);
NSLog(#"Error downloading message headers:%#", error);
}
NSMutableArray *currentMessages = [NSMutableArray arrayWithArray:fetchedMessages];
if( [currentMessages count] > 0 ) {
MCOIMAPMessage *lastMessage = [fetchedMessages lastObject];
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:#(lastMessage.uid) forKey:#"lastUID"];
[defaults synchronize];
completionHandler(UIBackgroundFetchResultNewData);
}
else {
completionHandler(UIBackgroundFetchResultNoData);
}
};
[fetchOperation start:fetchHandler];
and this is the logger when i execute that call
2015-01-21 18:02:46.723 App[5021:473470] mailcore - IMAP: * OK Gimap ready for requests from 181.167.207.42 b69mb75112208qhb
2015-01-21 18:02:46.725 App[5021:473470] mailcore - IMAP: 1 CAPABILITY
2015-01-21 18:02:46.955 App[5021:473470] mailcore - IMAP: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN
1 OK Thats all she wrote! b69mb75112208qhb
2015-01-21 18:02:46.955 App[5021:473470] mailcore - IMAP: 2 AUTHENTICATE XOAUTH2 dXNlcj1zYW50b21lZ29uemFsb0BnbWFpbC5jb20BYXV0aD1CZWFyZXIgeWEyOS5BZ0VQNnBQNFRJN1ZEMHlwempRNm01bTMwS2J0b0F6VzN6REdBbXc2dmh0VEF1TUJISVVaN3BobEtwY0M4dDlQRVFHcVhETHRlMU5VaFEBAQ==
2015-01-21 18:02:47.267 App[5021:473470] mailcore - IMAP: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT
2 OK santomegonzalo#gmail.com authenticated (Success)
2015-01-21 18:02:47.267 App[5021:473470] mailcore - IMAP: 3 COMPRESS DEFLATE
2015-01-21 18:02:47.518 App[5021:473470] mailcore - IMAP: 3 OK Success
2015-01-21 18:02:47.518 App[5021:473470] mailcore - IMAP: 4 ENABLE CONDSTORE
2015-01-21 18:02:47.767 App[5021:473470] mailcore - IMAP: * ENABLED CONDSTORE
4 OK Success
2015-01-21 18:02:47.767 App[5021:473470] mailcore - IMAP: 5 NAMESPACE
2015-01-21 18:02:48.016 App[5021:473470] mailcore - IMAP: * NAMESPACE (("" "/")) NIL NIL
5 OK Success
2015-01-21 18:02:48.017 App[5021:473470] mailcore - IMAP: 6 ID NIL
2015-01-21 18:02:48.267 App[5021:473470] mailcore - IMAP: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "http://support.google.com/mail" "version" "gmail_imap_150113.07_p0" "remote-host" "181.167.207.42")
6 OK Success
2015-01-21 18:02:48.268 App[5021:473470] mailcore - IMAP: 7 SELECT INBOX
2015-01-21 18:02:48.770 App[5021:473470] mailcore - IMAP: * FLAGS (\Answered \Flagged \Draft \Deleted \Seen $MailFlagBit1 $MailFlagBit0 $Phishing $Forwarded $MailFlagBit2 JunkRecorded $NotJunk NotJunk $NotPhishing $Junk)
* OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $MailFlagBit1 $MailFlagBit0 $Phishing $Forwarded $MailFlagBit2 JunkRecorded $NotJunk NotJunk $NotPhishing $Junk \*)] Flags permitted.
* OK [UIDVALIDITY 617846230] UIDs valid.
* 20472 EXISTS
* 0 RECENT
* OK [UIDNEXT 34091] Predicted next UID.
* OK [HIGHESTMODSEQ 4668463]
7 OK [READ-WRITE] INBO
2015-01-21 18:02:48.771 App[5021:473470] mailcore - IMAP: X selected. (Success)
2015-01-21 18:02:48.771 App[5021:473470] mailcore - IMAP: 8 UID FETCH 34092:* (UID ENVELOPE BODY.PEEK[HEADER.FIELDS (References)])
2015-01-21 18:02:49.405 App[5021:473470] mailcore - IMAP: * 20472 FETCH (UID 34090 MODSEQ (4668387) ENVELOPE ("Wed, 21 Jan 2015 20:31:46 -0000" "Subject" (("User" NIL "pullrequests-reply" "company.org")) (("User" NIL "toreply" "company.org")) (("User" NIL "toreply" "company.org")) ((NIL NIL "santomegonzalo" "gmail.com")) NIL NIL "<toreply#company.com>" " <toreply#company.com>") BODY[HEADER.FIELDS (References)] {52}
References: <toreply#company.com
)
8 OK Success

Related

TwilioChatClient There is no callbacks from channelWithSidOrUniqueName:completion: and getLastWithCount:completion:

we're stuck a bit with TwilioChatClient and can't sort out what's wrong. In some specific case there is no callback from some method.
For example:
twilioChatClient.channelsList()?.channel(withSidOrUniqueName: someSid, completion: { result, channel
// this block is never called
}
But we can fetch this channel using:
twilioChatClient.channelsList()?.subscribedChannels().first(where: { $0.sid == someSid || $0.uniqueName == someSid })
We send POST request to our server, where we create new channel. So the app get SID from response, and trying to connect to it
In the log after calling twilioChatClient.channelsList()?.channel(withSidOrUniqueName: "CH4155de0b7d374f34b027b5885b207ff9", completion... we see:
2021-01-13 18:15:51.167642+0200 <<<<TwilioChatClient: 0x28119a700>>>> - | Chat IPM | channels: [api] get channel CH4155de0b7d374f34b027b5885b207ff9
2021-01-13 18:15:51.167875+0200 <<<<TwilioChatClient: 0x28119a700>>>> - | Chat IPM | [Yq7OB] got channel from cache CH4155de0b7d374f34b027b5885b207ff9
2021-01-13 18:15:51.167928+0200 <<<<TwilioChatClient: 0x28119a700>>>> - | Chat IPM | channels: got from cache CH4155de0b7d374f34b027b5885b207ff9
So definitely Twilio found the channel, but why completion block is not called ?
After that we found workaround to get Channel directly from subscribedChannels() but we stuck with another issues with this channel (that was fetched from subscribedChannels())
If we try to fetch last message from channel using:
guard channel.status == .joined, channel.synchronizationStatus == .all else {
return
}
channel.messages?.getLastWithCount(100, completion: { [weak self] resulte, twilioMessages in
// this block is never called also
})
It seems very strange... It happens only for new channels, if we restart app - everything is working as expected.
There is no errors in
- (void)chatClient:(nonnull TwilioChatClient *)client errorReceived:(nonnull TCHError *)error;
There is no updates here :
- (void)chatClient:(nonnull TwilioChatClient *)client connectionStateUpdated:(TCHClientConnectionState)state
OR
- (void)chatClient:(nonnull TwilioChatClient *)client synchronizationStatusUpdated:(TCHClientSynchronizationStatus)status;
We also check:
chatClient.connectionState == .connected and chatClient.synchronizationStatus == .completed
before calling channel(withSidOrUniqueName: and getLastWithCount(
We're using the latest version 4.0.2 and it works the same in 3.1.1 (Xcode 12.2)
A bit more information. We have controller that we use for showing AR (ARKit). And when the scene is recognized, twilio stops working.
On viewDidLoad we start the timer that each second perform two actions
timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true, block: { [weak self] _ in
guard currentIndex < sids.count else { return }
guard isWorking == false else { return }
let sid = sids[currentIndex]
print("DEBUG: calling channelWithSidOrUniqueName \(sid)")
chatClient.channelsList()?.channel(withSidOrUniqueName: sid, completion: { result, channel in
print("DEBUG: get completion from channelWithSidOrUniqueName \(result.isSuccessful())")
guard let channel = channel else { return }
if channel.synchronizationStatus == .all {
print("DEBUG: synchronizationStatus == all")
}
if channel.status == .joined {
print("DEBUG: status == .joined")
}
lastChannel = channel
print("DEBUG: calling getLastWithCount \(channel.sid)")
channel.messages?.getLastWithCount(5, completion: { result, _ in
print("DEBUG: get completion from getLastWithCount \(channel.sid) \(result.isSuccessful())")
currentIndex += 1
isWorking = false
})
})
And if everything is okay we see in the logs like
2021-01-14 13:12:47.435842+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | channels: [api] get user channels
DEBUG: calling channelWithSidOrUniqueName CH1425bfdb625945c1ab43bdb440e9ee2a
2021-01-14 13:12:47.437993+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | channels: [api] get channel CH1425bfdb625945c1ab43bdb440e9ee2a
DEBUG: get completion from channelWithSidOrUniqueName true
DEBUG: synchronizationStatus == all
DEBUG: status == .joined
DEBUG: calling getLastWithCount Optional("CH1425bfdb625945c1ab43bdb440e9ee2a")
2021-01-14 13:12:47.438580+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [9HU8c] channel: [api] get messages
2021-01-14 13:12:47.438727+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [9HU8c] messages: [api] getLastMessages, count 5
2021-01-14 13:12:47.438798+0200 <<<<TwilioChatClient: 0x282715790>>>> - 8564 | Sync TSCollectionItemQueryActivity(3) | constructed
2021-01-14 13:12:47.438865+0200 <<<<TwilioChatClient: 0x282715790>>>> - 8564 | Sync TSCollectionItemQueryActivity(3) | start 2999
2021-01-14 13:12:47.438977+0200 <<<<TwilioChatClient: 0x282715790>>>> - 2827 | Sync List | query page id: 2999
2021-01-14 13:12:47.439049+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Sync CoreDataActivity | query [1] /v3/Services/IS566142b988d74af6bba32abbdb4a7474/Lists/ES6bb26aae7efb48b49ec0b232e2b1ba65/Items?Order=desc
2021-01-14 13:12:47.439117+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Twilsock Message::makePayload | Payload size 0
2021-01-14 13:12:47.439234+0200 <<<<TwilioChatClient: 0x282715790>>>> - 289 | Twilsock Client | sendUpstreamMessage, id = RQ8bfe33a7e9ac4507a060e1332a533eff
2021-01-14 13:12:47.648547+0200 <<<<TwilioChatClient: 0x282715790>>>> - 8564 | Sync TSCollectionItemQueryActivity(3) | response status 200 body 3349 bytes
2021-01-14 13:12:47.649263+0200 <<<<TwilioChatClient: 0x282715790>>>> - 8564 | Sync TSCollectionItemQueryActivity(3) | destructed
2021-01-14 13:12:47.649585+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [9HU8c] messages: query done, results count 3
DEBUG: get completion from getLastWithCount Optional("CH1425bfdb625945c1ab43bdb440e9ee2a") true
But after a while it stops working
2021-01-14 13:12:49.435863+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | channels: [api] get user channels
DEBUG: calling channelWithSidOrUniqueName CHa109c68be1454e5ca8bfffa3eedd37f2
2021-01-14 13:12:49.437479+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | channels: [api] get channel CHa109c68be1454e5ca8bfffa3eedd37f2
DEBUG: get completion from channelWithSidOrUniqueName true
DEBUG: synchronizationStatus == all
DEBUG: status == .joined
DEBUG: calling getLastWithCount Optional("CHa109c68be1454e5ca8bfffa3eedd37f2")
2021-01-14 13:12:49.438019+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [NRBeN] channel: [api] get messages
2021-01-14 13:12:49.438139+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [NRBeN] messages: [api] getLastMessages, count 5
2021-01-14 13:12:49.438248+0200 <<<<TwilioChatClient: 0x282715790>>>> - 8572 | Sync TSCollectionItemQueryActivity(3) | constructed
2021-01-14 13:12:49.438320+0200 <<<<TwilioChatClient: 0x282715790>>>> - 8572 | Sync TSCollectionItemQueryActivity(3) | start 3003
2021-01-14 13:12:49.438384+0200 <<<<TwilioChatClient: 0x282715790>>>> - 6750 | Sync List | query page id: 3003
2021-01-14 13:12:49.438451+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Sync CoreDataActivity | query [1] /v3/Services/IS566142b988d74af6bba32abbdb4a7474/Lists/ES0ca1135ad73e45d9b0f9e482ea1884b1/Items?Order=desc
2021-01-14 13:12:49.438551+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Twilsock Message::makePayload | Payload size 0
2021-01-14 13:12:49.438635+0200 <<<<TwilioChatClient: 0x282715790>>>> - 289 | Twilsock Client | sendUpstreamMessage, id = RQc3dafd4ae4a546fa8cebee15567d1d14
2021-01-14 13:12:49.629690+0200 <<<<TwilioChatClient: 0x282715790>>>> - 8572 | Sync TSCollectionItemQueryActivity(3) | response status 200 body 3349 bytes
2021-01-14 13:12:49.630136+0200 <<<<TwilioChatClient: 0x282715790>>>> - 8572 | Sync TSCollectionItemQueryActivity(3) | destructed
2021-01-14 13:12:49.630233+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [NRBeN] messages: query done, results count 3
2021-01-14 13:12:49.630302+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [NRBeN] messages: range 0:2
2021-01-14 13:12:49.630368+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [JUbw4] message: StateNoState->StateNotInitialized
2021-01-14 13:12:49.630433+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [JUbw4] message: StateNotInitialized->StateInitialized
2021-01-14 13:12:49.630498+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [v2zHz] message: StateNoState->StateNotInitialized
2021-01-14 13:12:49.630562+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [v2zHz] message: StateNotInitialized->StateInitialized
2021-01-14 13:12:49.630797+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [nPcGj] message: StateNoState->StateNotInitialized
2021-01-14 13:12:49.630863+0200 <<<<TwilioChatClient: 0x282715790>>>> - | Chat IPM | [nPcGj] message: StateNotInitialized->StateInitialized
And after that my method is waiting forever callback from getLastWithCount
I would be very grateful for any advice or suggestions
Twilio team confirmed that there is some issue when we use ARKit on iOS 14.3... 14.4
https://github.com/twilio/twilio-chat-ios/issues/22

How to join more than 2 regions with Apache Geode?

I've been trying to query some regions and i'm failing to join more than 2 of them. I set that up in a Java test to run them more easily but it fails all the same in pulse.
#Test
public void test_geode_join() throws QueryException {
ClientCache cache = new ClientCacheFactory()
.addPoolLocator(HOST, LOCATOR_PORT)
.setPoolSubscriptionEnabled(true)
.setPdxSerializer(new MyReflectionBasedAutoSerializer())
.create();
{
#SuppressWarnings("unchecked")
SelectResults<StructImpl> r = (SelectResults<StructImpl>) cache.getQueryService()
.newQuery("SELECT itm.itemId, bx.boxId " +
"FROM /items itm, /boxs bx " +
"WHERE itm.boxId = bx.boxId " +
"LIMIT 5")
.execute();
for (StructImpl v : r) {
System.out.println(v);
}
}
{
#SuppressWarnings("unchecked")
SelectResults<StructImpl> r = (SelectResults<StructImpl>) cache.getQueryService()
.newQuery("SELECT bx.boxId, rm.roomId " +
"FROM /boxs bx, /rooms rm " +
"WHERE bx.roomId = rm.roomId " +
"LIMIT 5")
.execute();
for (StructImpl v : r) {
System.out.println(v);
}
}
{
// That fails
#SuppressWarnings("unchecked")
SelectResults<StructImpl> r = (SelectResults<StructImpl>) cache.getQueryService()
.newQuery("SELECT itm.itemId, bx.boxId, rm.roomId " +
"FROM /items itm, /boxs bx, /rooms rm " +
"WHERE itm.boxId = bx.boxId " +
"AND bx.roomId = rm.roomId " +
"LIMIT 5")
.execute();
for (StructImpl v : r) {
System.out.println(v);
}
}
}
The first 2 queries work fine and respond in an instant but the last query holds until it timeouts. I get the following logs
[warn 2018/02/06 17:33:17.155 CET <main> tid=0x1] Pool unexpected socket timed out on client connection=Pooled Connection to hostname:31902: Connection[hostname:31902]#1978504976)
[warn 2018/02/06 17:33:27.333 CET <main> tid=0x1] Pool unexpected socket timed out on client connection=Pooled Connection to hostname2:31902: Connection[hostname2:31902]#1620459733 attempt=2)
[warn 2018/02/06 17:33:37.588 CET <main> tid=0x1] Pool unexpected socket timed out on client connection=Pooled Connection to hostname3:31902: Connection[hostname3:31902]#422409467 attempt=3)
[warn 2018/02/06 17:33:37.825 CET <main> tid=0x1] Pool unexpected socket timed out on client connection=Pooled Connection to hostname3:31902: Connection[hostname3:31902]#422409467 attempt=3). Server unreachable: could not connect after 3 attempts
[info 2018/02/06 17:33:37.840 CET <Distributed system shutdown hook> tid=0xd] VM is exiting - shutting down distributed system
[info 2018/02/06 17:33:37.840 CET <Distributed system shutdown hook> tid=0xd] GemFireCache[id = 1839168128; isClosing = true; isShutDownAll = false; created = Tue Feb 06 17:33:05 CET 2018; server = false; copyOnRead = false; lockLease = 120; lockTimeout = 60]: Now closing.
[info 2018/02/06 17:33:37.887 CET <Distributed system shutdown hook> tid=0xd] Destroying connection pool DEFAULT
And it ends up crashing
org.apache.geode.cache.client.ServerConnectivityException: Pool unexpected socket timed out on client connection=Pooled Connection to hostname3:31902: Connection[hostname3:31902]#422409467 attempt=3). Server unreachable: could not connect after 3 attempts
at org.apache.geode.cache.client.internal.OpExecutorImpl.handleException(OpExecutorImpl.java:798)
at org.apache.geode.cache.client.internal.OpExecutorImpl.handleException(OpExecutorImpl.java:623)
at org.apache.geode.cache.client.internal.OpExecutorImpl.execute(OpExecutorImpl.java:174)
at org.apache.geode.cache.client.internal.OpExecutorImpl.execute(OpExecutorImpl.java:115)
at org.apache.geode.cache.client.internal.PoolImpl.execute(PoolImpl.java:763)
at org.apache.geode.cache.client.internal.QueryOp.execute(QueryOp.java:58)
at org.apache.geode.cache.client.internal.ServerProxy.query(ServerProxy.java:70)
at org.apache.geode.cache.query.internal.DefaultQuery.executeOnServer(DefaultQuery.java:456)
at org.apache.geode.cache.query.internal.DefaultQuery.execute(DefaultQuery.java:338)
at org.apache.geode.cache.query.internal.DefaultQuery.execute(DefaultQuery.java:319)
at local.test.geode.GeodeTest.test_geode_join(GeodeTest.java:226)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
I tried to set timeouts at 60 seconds but i'm still not getting any results.
All regions are configured like this:
Type | Name | Value
------ | --------------- | --------------------
Region | data-policy | PERSISTENT_REPLICATE
| disk-store-name | regionDiskStore1
| size | 1173
| scope | distributed-ack
Am I missing anything here ?
Based on all the information provided, it looks like you are doing everything correct. I tried to reproduce in a simple test (similar test) and the test returns 5 results. However, if one of the predicates did not match, it could cause the query to take a lot longer to join enough rows to find a tuple that matches.
Below is a sample test that does not have an issue, but if I modify the test to put into region3 only portfolios with ID = -1. Then the test "hangs" trying to find 5 rows that fulfill the search criteria (it has to join 1000 * 1000 * 1000 rows which takes awhile to do). In the end the query will not find an p3.ID = p1.ID. Is it possible that the itm.boxIds just do not match box.boxId often enough so it takes a lot longer to find ones that do?
public void testJoinMultipleReplicatePersistentRegionsWithLimitClause() throws Exception {
String regionName = "portfolio";
Cache cache = serverStarterRule.getCache();
assertNotNull(cache);
Region region1 =
cache.createRegionFactory(RegionShortcut.REPLICATE_PERSISTENT).create(regionName + 1);
Region region2 =
cache.createRegionFactory(RegionShortcut.REPLICATE_PERSISTENT).create(regionName + 2);
Region region3 =
cache.createRegionFactory(RegionShortcut.REPLICATE_PERSISTENT).create(regionName + 3);
for ( int i = 0; i < 1000; i++) {
Portfolio p = new Portfolio(i);
region1.put(i, p);
region2.put(i, p);
region3.put(i, p); //modify this line to region3.put(i, new Portfolio(-1)) to cause query to take longer
}
QueryService queryService = cache.getQueryService();
SelectResults results = (SelectResults) queryService
.newQuery("select p1.ID, p2.ID, p3.ID from /portfolio1 p1, /portfolio2 p2, /portfolio3 p3 where p1.ID = p2.ID and p3.ID = p1.ID limit 5").execute();
assertEquals(5, results.size());
}

GCDWebServer for streaming

I was trying to stream a mp4 video from a remote server on a iOS device. I somehow got
[ERROR] Error while writing to socket 15: Broken pipe (32) after a few writes.
Not sure where is wrong. Can you kindly give any advice?
iOS re-routing requests w/ GCDWebServer (not redirecting)
Thanks!
Rao
#property (nonatomic, strong) GCDWebServerBodyReaderCompletionBlock cb;
[_webServer addDefaultHandlerForMethod:#"GET"
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
GCDWebServerStreamedResponse* response = [GCDWebServerStreamedResponse responseWithContentType:#"application/octet-stream" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) {
NSString * realURL = #"https://ia800309.us.archive.org/2/items/Popeye_Nearlyweds/Popeye_Nearlyweds_512kb.mp4";
self.cb = completionBlock;
NSURLSessionDataTask * dataTask = [self.session dataTaskWithURL:[[NSURL alloc] initWithString:realURL]] ;
}];
return response;
}];
(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
{
self.response = response;
completionHandler(NSURLSessionResponseAllow);
}
(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
{
NSLog(#"got data size == %lu", data.length);
self.cb(data, nil);
}
(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
self.cb([NSData data], nil);
}
[DEBUG] Did open IPv4 listening socket 6
[DEBUG] Did open IPv6 listening socket 7
[INFO] GCDWebServer started on port 8080 and reachable at http://192.168.1.27:8080/
2016-02-23 15:34:39.096 Proxy2Proxy[5315:1148991] Visit http://192.168.1.27:8080/ in your web browser
[DEBUG] Did open connection on socket 15
[DEBUG] Did connect
[DEBUG] Did start background task
[DEBUG] Connection received 370 bytes on socket 15
[DEBUG] Connection on socket 15 preflighting request "GET /https://ia800309.us.archive.org/2/items/Popeye_Nearlyweds/Popeye_Nearlyweds_512kb.mp4" with 370 bytes body
[DEBUG] Connection on socket 15 processing request "GET /https://ia800309.us.archive.org/2/items/Popeye_Nearlyweds/Popeye_Nearlyweds_512kb.mp4" with 370 bytes body
[DEBUG] Connection sent 175 bytes on socket 15
2016-02-23 15:34:47.488 Proxy2Proxy[5315:1148991] got data size == 16059
[DEBUG] Connection sent 16067 bytes on socket 15
2016-02-23 15:34:47.488 Proxy2Proxy[5315:1148991] got data size == 32768
[DEBUG] Connection sent 32776 bytes on socket 15
2016-02-23 15:34:47.489 Proxy2Proxy[5315:1148991] got data size == 32768
[DEBUG] Connection sent 32776 bytes on socket 15
2016-02-23 15:34:47.489 Proxy2Proxy[5315:1148991] got data size == 98304
2016-02-23 15:34:47.490 Proxy2Proxy[5315:1148991] got data size == 16384
[DEBUG] Connection sent 98313 bytes on socket 15
[DEBUG] Connection sent 16392 bytes on socket 15
2016-02-23 15:34:47.506 Proxy2Proxy[5315:1148991] got data size == 16384
[DEBUG] Connection sent 16392 bytes on socket 15
2016-02-23 15:34:47.517 Proxy2Proxy[5315:1148991] got data size == 16384
[DEBUG] Connection sent 16392 bytes on socket 15
2016-02-23 15:34:47.530 Proxy2Proxy[5315:1148991] got data size == 16384
[DEBUG] Connection sent 16392 bytes on socket 15
2016-02-23 15:34:47.545 Proxy2Proxy[5315:1148991] got data size == 16384
[ERROR] Error while writing to socket 15: Broken pipe (32)

RestKit Core Data NSError dealloc Crash

Trying to get to the bottom of an issue I've been seeing in production builds and FINALLY was able to reproduce it while testing. Using RestKit v0.23.1, when doing an RKManagedObjectRequestOperation using the following code (while plugged into instruments) I get "An Objective-C message was sent to a deallocated 'NSError' object (zombie)" and the app crashes every time there's objects in the response JSON - if the response is something like "objects = ();" there's no crash - so I'm guessing it's somewhere in the RestKit/Core Data mapping or storage?
RKManagedObjectRequestOperation *objectRequestOperation = [_objectManager managedObjectRequestOperationWithRequest:request managedObjectContext:_objectManager.managedObjectStore.mainQueueManagedObjectContext success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
DDLogInfo(#"INSIDE SUCCESS BLOCK");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
DDLogInfo(#"INSIDE ERROR BLOCK");
}];
[objectRequestOperation setWillMapDeserializedResponseBlock:^id(id deserializedResponseBody) {
DDLogInfo(#"Response JSON: %#", deserializedResponseBody);
return deserializedResponseBody;
}];
objectRequestOperation.savesToPersistentStore = YES;
[objectRequestOperation start];
The raw JSON is properly logged inside the setWillMapDeserializedResponseBlock, but the logs inside the success and error block are never reached. Here is the stack trace I get back from crashlytics:
Thread : Crashed: NSOperationQueue Serial Queue
0 libobjc.A.dylib 0x37dd4626 objc_msgSend + 5
1 Foundation 0x2df5802d -[NSError dealloc] + 60
2 libobjc.A.dylib 0x37dd9b6b objc_object::sidetable_release(bool) + 174
3 libobjc.A.dylib 0x37dda0d3 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 358
4 CoreFoundation 0x2d569501 _CFAutoreleasePoolPop + 16
5 Foundation 0x2df69999 -[__NSOperationInternal _start:] + 1064
6 Foundation 0x2e00d745 __NSOQSchedule_f + 60
7 libdispatch.dylib 0x382b8cbd _dispatch_queue_drain + 488
8 libdispatch.dylib 0x382b5c6f _dispatch_queue_invoke + 42
9 libdispatch.dylib 0x382b95f1 _dispatch_root_queue_drain + 76
10 libdispatch.dylib 0x382b98dd _dispatch_worker_thread2 + 56
11 libsystem_pthread.dylib 0x383e4c17 _pthread_wqthread + 298
This isn't a problem with RestKit. I've seen this problem frequently and it actually looks like the over-release actually happens in Apple's code. The problem happens when you try to save to a Core Data store and it fails. Core Data reports an error as it should, but that error is mishandled.
I had a few scenarios causing the save failures and this is how I fixed them:
The data store is inaccessible because of the Data Protection API.
Either busy wait and let your app fail to launch like this:
while(![[UIApplication sharedApplication] isProtectedDataAvailable]) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5f]];
}
Or disable protection if the data in your store isn't sensitive like this:
[_coordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:url
options:#{NSPersistentStoreFileProtectionKey:NSFileProtectionNone}
error:&error];
The important thing is that you don't try to save until you can access the file. If you can re-structure you code to prevent accessing the database when it is inaccessible that is good too. You can use the Data Protection API application delegate methods to trigger that mechanism.
The data store is corrupted - The best thing to do here is to delete the store and start over. Here is a good way to detect a corrupted store using the sqlite library directly.
#import <sqlite3.h>
sqlite3 *dbConnection;
if (sqlite3_open([[url absoluteString] UTF8String], &dbConnection) != SQLITE_OK) {
NSLog(#"[SQLITE] Unable to open database!");
}
sqlite3_stmt *statement = nil;
sqlite3_prepare_v2(dbConnection, "PRAGMA quick_check;", -1, &statement, NULL);
NSString *result = nil;
while (sqlite3_step(statement) == SQLITE_ROW) {
for (int i=0; i<sqlite3_column_count(statement); i++) {
int colType = sqlite3_column_type(statement, i);
if (colType == SQLITE_TEXT) {
const unsigned char *col = sqlite3_column_text(statement, i);
result = [NSString stringWithFormat:#"%s", col];
} else {
NSLog(#"[SQLITE] UNKNOWN DATATYPE");
}
}
}
sqlite3_close(dbConnection);
This runs a sqlite PRAGMA query to perform an integrity check. I use quick_check, but you could also use integrity_check if you are willing to wait the extra time. You can tell things are good using [result isEqualToString:#"ok"]

IMAPMessage.getRecipients() and IMAPMessage.getAllRecipients() return null

I'm writing an IMAP message poller (to be used from within a business app). I'm able to connect, iterate through the messages in Inbox, read their headers and content but calls to getAllRecipients() and getRecipients(Message.RecipientType.TO) always return null.
Message messages[] = inbox.getMessages();
for (Message message : messages) {
IMAPMessage imapMessage = (IMAPMessage) message;
Address[] toRecipients = imapMessage.getRecipients(Message.RecipientType.TO);
Address[] allRecipients = imapMessage.getAllRecipients();
This is puzzling. The messages in the Inbox have been sent with regular mail clients so there is nothing unusual with them.
The IMAP server is running Dovecot.
* OK Dovecot ready.
A0 CAPABILITY
* CAPABILITY IMAP4rev1 SASL-IR SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ IDLE CHILDREN NAMESPACE LOGIN-REFERRALS STARTTLS AUTH=PLAIN
A0 OK Capability completed.
This is the relevant traffic dump captured with Wireshark while doing the above (and also calling imapMessage.getContent()).
A3 SELECT Inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 2 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1277135188] UIDs valid
* OK [UIDNEXT 3] Predicted next UID
A3 OK [READ-WRITE] Select completed.
A4 FETCH 1 (BODYSTRUCTURE)
* 1 FETCH (BODYSTRUCTURE ("text" "plain" ("charset" "us-ascii") NIL NIL "7bit" 12 1 NIL NIL NIL))
A4 OK Fetch completed.
A5 FETCH 1 (BODY[TEXT]<0.12>)
* 1 FETCH (BODY[TEXT]<0> {12}
here it is
)
A5 OK Fetch completed.
A6 FETCH 1 (FLAGS)
* 1 FETCH (FLAGS (\Seen))
A6 OK Fetch completed.
A7 FETCH 1 (BODY.PEEK[HEADER])
* 1 FETCH (BODY[HEADER] {399}
Return-Path: <EDITED>
Received: from EDITED; Sat, 5 Jun 2010 15:33:13 -0400
Date: Sat, 5 Jun 2010 15:32:40 -0400
From: EDITED
Message-Id: <EDITED>
Subject: Test Message
Lines: 1
)
A7 OK Fetch completed.
A8 FETCH 1 (ENVELOPE INTERNALDATE RFC822.SIZE)
* 1 FETCH (INTERNALDATE "05-Jun-2010 15:33:32 -0400" RFC822.SIZE 411 ENVELOPE ("Sat, 5 Jun 2010 15:32:40 -0400" "Test Message" ((NIL NIL "myediteduser" "myediteddomain")) ((NIL NIL "myediteduser" "myediteddomain")) ((NIL NIL "myediteduser" "myediteddomain")) NIL NIL NIL NIL "<EDITED>"))
A8 OK Fetch completed.
A9 FETCH 2 (BODYSTRUCTURE)
* 2 FETCH (BODYSTRUCTURE (("text" "plain" ("charset" "iso-8859-1") NIL NIL "quoted-printable" 8 0 NIL NIL NIL)("text" "html" ("charset" "iso-8859-1") NIL NIL "quoted-printable" 341 9 NIL NIL NIL) "alternative" ("boundary" "----=_NextPart_000_0003_01CB1137.CCF78C80") NIL NIL))
A9 OK Fetch completed.
Any hints are appreciated. I don't know if there is anything else I should be calling or if there is a setting in the IMAP server. I've looked at all methods of the IMAPMessage in case there was something to run before calling getRecipients() and getAllRecipients() but there was nothing. Also googled for a while and found nothing else I should have called.
Just to close it: this was an issue with the mail server setup and it's now fixed.

Resources