Riak is creating siblings of expired keys in bitcask bucket types - riak

I have a Riak server using multi backend storage with the following configuration:
...
storage_backend = multi
multi_backend.bitcask_mult.storage_backend = bitcask
multi_backend.bitcask_mult.bitcask.expiry = 10s
...
I have checked that the following sequence of steps works correctly.
Put a new value with key key-1.
Get the value with key key-1 returns the expected value.
Wait 15 seconds.
Try to get the value with key-1. This returns nothing, as the key has expired.
So far so good.
However, if now I put the value with the same key again...
Put a new value with key key-1
Get the value with key-1 returns two siblings!
I have waited for hours between steps #4 and #5 (just in case the expiration had to be flushed or something like that), with no luck.
I can address this situation handling the siblings, which is something that I do anyway for some other buckets I work with, but I wasn't expecting to have to deal with "expired siblings"!
I have read something about automatic expiration and Riak Search but I don't think this is the case.
Am I doing something wrong? Am I missing something?
Thanks.

Void, expiration is working but you are running into a problem I will call "Expiration <> Delete". When an object expires in Bitcask a tombstone is created by Bitcask and the backend returns not_found to any requests for that object BUT the object isn't deleted. The object gets "deleted" when the oldest object in the Bitcask data file expires and the whole file is expired. At that point a new file is created.
Until a new file is created in Bitcask the object actually still exists even though Bitcask is returning not_found. When you write to "deleted" key the Bitcask the last-modified time is getting updated essentially resurrecting it.
To test this theory you can actually stop Riak and restart it. Restarting Riak will cause Bitcask to create a new data file and will keep you from getting siblings.
Long story short you still need to deal with siblings in this case.

Related

Google Calendar - SyncToken is missing in API response

I don't see nextSyncToken in the response. I followed the doc(https://developers.google.com/calendar/api/guides/sync) and paginated using nextPageToken but I couldn't see the nextSyncToken on the last page.
API Used: GET /calendars/primary/events?maxResults=10&singleEvents=true&pageToken=********
I don't know whether if I miss anything here. Could anyone help me with this?
I have seen from the response link on the other answer comment that you are using orderBy on the request.
This is why the nextSyncToken is not showing up.
As mentioned on the documentation on Events: list -> Parameters -> syncToken:
Token obtained from the nextSyncToken field returned on the last page of results from the previous list request. It makes the result of this list request contain only entries that have changed since then. All events deleted since the previous list request will always be in the result set and it is not allowed to set showDeleted to False.
There are several query parameters that cannot be specified together with nextSyncToken to ensure consistency of the client state.
These are:
iCalUID
orderBy
privateExtendedProperty
q
sharedExtendedProperty
timeMin
timeMax
updatedMin
If the syncToken expires, the server will respond with a 410 GONE response code and the client should clear its storage and perform a full synchronization without any syncToken.
Learn more about incremental synchronization.
Optional. The default is to return all entries.
You should remove the orderBy from the request to get the syncToken
Could you please provide the response from gcalendar API? It's hard to say more without detail information. I event don't know which language are you using.
Try to use a vendor library to sort that out:
a) https://packagist.org/packages/google/apiclient (for PHP)
b) https://www.npmjs.com/package/google-calendar (for JavaScript)
and/or
Try to use alternative endpoint: GET https://www.googleapis.com/calendar/v3/calendars/calendarId/events.

Loosing session variable data from one page to the other in VB.NET

I am a bit new to VB.NET. I have a page that sets 2 session variables and does a redirect to second page. The second pages is at least using one of the session variables. I can tell because on the second page, if the session variable is not correct the user is redirected to an access denied page. The second page also uses the session variable in question. It will read it an fill a gridview based on the value of the variable. I set the variable like so
Session("ID") = Convert.ToInt32(a_value)
and on the second page I retrieve the variable like this
a_page_variable = Session("ID")
What I find strange is that when I run this code in visual studio it works as expected but when I deploy and run it, I get 0 from my session variable instead of the true value of "a_value". I have tried a few things like making sure the data types match up from page to page and trying different ways to retrieve the variable such as
Session("userID")
and
CType(Session.Item("userID"), Int32)
I've also tried to see what is coming in to the second page by using
Response.Write
I also tried to use SQL Profiler to see what kind of call is being made to fill the gridview but I haven't had any luck. The gridview gives me an empty dataset and the Profiler does not detect a call being made from the application. I thought working with session variables was pretty straight forward but obviously, I am missing something.
Thanks for your help,
Billy
One possibility (and the only one that could be guessed at with how little information we have) could be the response.redirect causing the application to terminate due to an exception.
When redirecting, you want to always pass a false, and then call complete request.
Response.Redirect(urlstring, False)
Response.CompleteRequest()
not following these steps can cause exceptions, which may drop session.
Additionally, resolve virtual paths, as some browsers (mobile especially) can see those redirects as new requests entirely, thus generating new session tokens.
Dim urlstring As String
urlstring = Page.ResolveUrl("~/default.aspx")
that said, there are a number of possible causes for this situation.
Application Pool restarts
App Domain restarted
Code changing value unexpectedly
AV tinkering with files
deployed to web farm
With the description provided above, we just don't have enough information to really troubleshoot.
Thank you ADyson, Stephen Wrighton and everyone else who took a stab at helping me figure this out. I was able to find out what was going on by adding code that wrote to a log file on the server. Found the logging code here. I found that I never reached the code that set the session variable and that is the reason it never populated on the second page. I was trying to get the logon name for the user by using Environment.UserName which will return the user name of the person who is currently logged on to the operating system. But what I really wanted to do was get the logon name of the user that was visiting my site. For this I used User.Identity.Name. This works great when you need to know which user from an Active Directory domain is visiting your site.

IndexOutOfBounds when executing a NamedQuery twice

I'm trying to make a web application for the first time, and I use all kinds of tutorials and help of any kind, but I don't get why this happens. Everything worked all right until now:
I'm trying to transmit a "User" attribute between servlets, and I'm doing so by sending part of it as an attribute (using RequestDispatcher or HTML forms), and looking up the rest of it in a database, like this:
String user = (String) request.getAttribute("txt");
Users info = (Users) emf.createEntityManager().createNamedQuery("Users.findByUsername").setParameter("username",user).getResultList().get(0);
Username is Unique key, and the code for the NamedQuery is
#NamedQuery(name = "Users.findByUsername", query = "SELECT u FROM Users u WHERE u.username = :username)
The first time I use this, it works and I get the expected result, but, if I come back to the same servlet or I use the same code again in other servlet, I get java.lang.IndexOutOfBoundsExpcetion: Index: 0, Size: 0
How can this happen if I didn't modify the database at any moment?
Any help would be appreciated.
Seems like your request attribute "txt" is null the second time. It's a request attribute, so it will be only valid during the request. If you don't store it or submit it every time it will be null.
A null as username will produce an empty list. The attempt to read the first element of an empty list produces the IndexOutOfBoundsException.
Use a session attribute or resubmit the attribute every time and it will work.

What response code is appropriate for this situation?

I'm developing a webgame. As part of the game, you start out with a limited set of features, and you unlock more of them as you play.
For instance, you unlock /fields as part of step 3 in the tutorial. But what if you just navigate to /fields in the address bar?
I'm trying to work out what would be the best status code to respond with.
403 seems ideal since the user is forbidden from accessing the page until they unlock it.
404 also makes sense since the page technically "doesn't exist" until it is unlocked and also prevents users from being able to tell the difference between a page that doesn't exist and one that they just haven't unlocked yet.
But in both cases I've had some users report issues with the browser cacheing the 403/404 result and not letting them access the page even after unlocking it unless they purge the cache entirely.
I'm wondering if I should keep using 403 or 404, or should I use an unused 4XX code such as 442 with a custom statusText, or even jokingly send HTTP/1.1 418 I'm A Teapot in response to a user poking around where they shouldn't be.
I need a good, solid reason why one option should be used over the others.
tl;dr 409 Conflict would be an idea, but perhaps you have problems with caching. In this case a cache-buster to force a reload will work.
Long explanation
Perhaps a 409 Conflict status code would make sense:
10.4.10 409 Conflict
The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required.
Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type.
It would make sense, because the resource is only available after the user did the tutorial. Before that the resource is in an «invalid» state. And the user is able to resolve this conflict by completing the tutorial.
Later I investigated the case a little more and I discovered that the devil is in the detail. Let's read the specification for 403 Forbidden and 404 Not Found.
10.4.4 403 Forbidden
The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
Important is the specification that «the request SHOULD NOT be repeated». A browser which never re-requests a 403 page might do the right thing. However, let's continue with 404:
10.4.5 404 Not Found
The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent.
[omitted]
Now we have a problem! Why would your 404 pages be cached if the specification allows them to be temporary?
Perhaps in your setup you have caching configured not correctly for your 403 and 404 pages. If this is so, please consult this answer on StackOverflow. It gives a detailed answer about caching 4xx pages.
If you don't want to mess with caching headers, use a so-called cache-buster and pass the system time like this (assuming PHP as your web language):
<a href="/fields?<?php echo time(); ?>">
This produces URLs like /fields?1361948122, increasing every second. It's a variant of the solution proposed by Markus A.
I assume the querystring 1361948122 is ignored by your resource. If it is not, pass the cache-buster in a querystring parameter instead, for example t=1361948122 and make sure that the parameter t is not evaluated by your resource.
In terms of the intended purpose of the HTTP error codes, I would definitely go with 403 Forbidden, because the page does exist (404 is out), but the user is forbidden to access it for now (and this restriction is not due to a resource conflict, like concurrent modification, but due to the user's account status, i.e. 409 is out as well in my opinion). Another sensible option based on it's intended purpose could have been 401, but as nalply already noted in his comment, this code triggers some, if not all, browsers to display a login dialog, as it implies that using the standard web-authentication mechanism can resolve the issue. So, it would definitely not be an option for you here.
Two things seem a little "misfitting" in the description of 403, so let me address them:
Authorization will not help ...: This only talks about the authorization mechanism inside the HTTP protocol and is meant to distinguish 403 from 401. This statement does not apply to any form of custom authorization or session state management.
... the request SHOULD NOT be repeated ...: A request must always be seen in the session context, so if the session context of the user changes (he unlocks a feature) and then he retries accessing the same resource, that is a different request, i.e. there is no violation of this suggestion.
Of course, you could also define your own error code, but since it probably won't be reserved in any official way, there is no guarantee that some browser manufacturer isn't going to intentionally or accidentally use exactly that code to trigger a specific (debugging) action. It's unlikely, but not disallowed.
418 could be OK, too, though. :)
Of course, if you would like to specifically obscure the potential availability of features, you could also decide to use 404 as that is the only way to not give a nosy user any hints.
Now, to your caching issue:
Neither one of these status codes (403, 404, 409, 418) should trigger the browser to cache the page against your will more than any other. The problem is that many browser simply try to cache everything like crazy to be extra snappy. Opera is the worst here in my opinion. I've been pulling my hair out many times over these things. It SHOULD be possible to work it all out with the correct header settings, but I've had situations where either the browser or the server or some intermediate proxy decided to ignore them and break my page anyways.
The only sure-fire way that I have found so far that absolutely positively guarantees a reload is to add a dummy request parameter like /fields?t=29873, where 29873 is a number that is unique for every request you make within any possibly relevant time scales. On the server, of course, you can then simply ignore this parameter. Note that it is not enough to simply start at 1 when your user first opens your page and then count up for following requests, as browsers might keep the cache around across page-reloads.
I do my web-development in Java (both server and client-side using GWT) and I use this code to generate the dummy "numbers":
private static final char[] base64chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_.".toCharArray();
private static int tagIndex = 0;
/**
* Generates a unique 6-character tag string that is guaranteed to not repeat
* for about 400 days, if this function is, on average, not called more often
* than twice every millisecond.
*
* #return the tag string
*/
public static String nowTag() {
int tag = (int) ((System.currentTimeMillis() >>> 5)); // adjust
char[] result = new char[6];
result[5] = base64chars[(tagIndex++) & 63];
result[4] = base64chars[tag & 63];
tag >>>= 6;
result[3] = base64chars[tag & 63];
tag >>>= 6;
result[2] = base64chars[tag & 63];
tag >>>= 6;
result[1] = base64chars[tag & 63];
tag >>>= 6;
result[0] = base64chars[tag & 63];
return new String(result);
}
It uses the system's clock in combination with a counter to be able to provide up to about two guaranteed unique values every ms. You might not need this speed, so you can feel free to change the >>> 5 that I marked with "adjust" to fit your needs. If you increase it by 1, your rate goes down by a factor of two and your uniqueness time-span doubles. So, for example, if you put >>> 8 instead, you can generate about 1 value every 4 ms and the values should not repeat for 3200 days. Of course, this guarantee that the values will not repeat will go away if the user messes with the system clock. But since these values are not generated sequentially, it is still very unlikely that you will hit the same number twice. The code generates a 6-character text-string (base64) rather than a decimal number to keep the URLs as short as possible.
Hope this helps. :)
I feel there is no need to throw an error code, in spite you just display a message like
You have to be Level XX to access this page or something funny like Come back when you grow-up
with code 200-OK itself, so there will be no cache problem and objective is also achieved.

Read a website using PL/SQL

I want to call a website using PL/SQL and get the return value of it.
The main sense of the process is the call itself, I don't really need the given return value of the website.
How is it possible to execute a webcall as simple as possible in PL/SQL?
Thanks for help!
Flo
It is very simple:
response = utl_http.request(url);
where response is VARCHAR2(2000) as this call returns only the first 2000 bytes of the response.
Of course, you can retrieve the whole response document too, in 2000 bytes chunks. You can additionally set timeout, response error check, etc.
Available in Oracle 10g+. See documentation.

Resources