-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
14 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1179,7 +1179,7 @@ RavenDB uses to allow that. | |
|
||
The most obvious way to get an identifier is to ask the user to generate it. This is typically done when you want an | ||
identifier that's of some meaningful value. For example, `people/[email protected]` or `accounts/591-192` are two document IDs | ||
that the developer can choose. Listing 2.18 shows how you can provide an external identifier when creating documents. | ||
that the developer can choose. Listing 2.19 shows how you can provide an external identifier when creating documents. | ||
|
||
```{caption="Saving a new person with an externally defined document ID" .cs} | ||
using (var session = store.OpenSession()) | ||
|
@@ -1431,7 +1431,7 @@ RavenDB uses the metadata to store several pieces of information about the docum | |
|
||
You can use the metadata to store your own values. For example, `Last-Modified-By` is a common metadata property that's | ||
added when you want to track who changed a document. From the client side, you can access the document metadata using the | ||
code in Listing 2.19. | ||
code in Listing 2.20. | ||
|
||
```{caption="Modifying the metadata of a document" .cs} | ||
using (var session = store.OpenSession()) | ||
|
@@ -1483,7 +1483,7 @@ with multi-thread solutions is the atomic compare-and-swap operation. From code, | |
`Interlocked.CompareExchange` when using C#. Because this operation is so useful, it's supported at the hardware level with | ||
the `CMPXCHG` assembly instruction. In a similar way, RavenDB offers a distributed compare-exchange feature. | ||
|
||
Let's take a look at Listing 2.20, for a small sample of what this looks like in code. | ||
Let's take a look at Listing 2.21, for a small sample of what this looks like in code. | ||
|
||
```{caption="Using compare exchange to validate unique username in a distributed system" .cs} | ||
var cmd = new PutCompareExchangeValueOperation<string>( | ||
|
@@ -1497,7 +1497,7 @@ if (result.Successful) | |
} | ||
``` | ||
|
||
The code in Listing 2.20 uses `PutCompareExchangeValueOperation` to submit a compare-exchange operation to the cluster | ||
The code in Listing 2.21 uses `PutCompareExchangeValueOperation` to submit a compare-exchange operation to the cluster | ||
at large. This operation compares the existing index for `names/john` with the expected index (in this case, `0`, meaning | ||
we want to create a new value). | ||
If successful, the cluster will store the value `users/1-A` for the key `names/john`. However, if there is already a value | ||
|
@@ -1507,7 +1507,7 @@ and can decide how to handle things from that point (show an error to the user, | |
The most important aspect of this feature is the fact that this is a cluster-wide, distributed operation. It is guaranteed | ||
to behave properly even if you have concurrent requests going to separate nodes. This feature is a low-level one; it is meant | ||
to be built upon by the user to provide more sophisticated features. | ||
For example, in Listing 2.20, we ensure a unique username for each user using a method that is resilient to failures, network | ||
For example, in Listing 2.21, we ensure a unique username for each user using a method that is resilient to failures, network | ||
partitions, etc. | ||
|
||
You can see how this is exposed in the studio in Figure 2.14. | ||
|
@@ -1517,7 +1517,7 @@ You can see how this is exposed in the studio in Figure 2.14. | |
We'll talk more about compare-exchange values in Chapter 6. For now, it's good to remember that they're there and can help | ||
you make distributed decisions in a reliable manner. A compare-exchange value isn't limited to just a string. You can also | ||
use a complex object, a counter, etc. However, remember that these are _not_ documents. You can read the current value of | ||
compare-exchange value using the code in Listing 2.21. Aside from checking the current value of the key, you get the | ||
compare-exchange value using the code in Listing 2.22. Aside from checking the current value of the key, you get the | ||
current index, which you can then use in the next call to `PutCompareExchangeValueOperation`. | ||
|
||
```{caption="Reading an existing compare exchange value by name" .cs} | ||
|
@@ -1530,14 +1530,14 @@ key will be (as in the case of creating a new username and checking the name isn | |
compare-exchange key in a document that you'll query and then use the key from the document to make the compare-exchange | ||
operation. | ||
|
||
If you know the name of the compare-exchange value, you can use it directly in your queries, as shown in Listing 2.22. | ||
If you know the name of the compare-exchange value, you can use it directly in your queries, as shown in Listing 2.23. | ||
|
||
```{caption="Querying for documents using cmpxchg() values" .sql} | ||
from Users | ||
where id() == cmpxchg('names/john') | ||
``` | ||
|
||
The query in Listing 2.22 will find a document whose ID is located in the `names/john` compare-exchange value. We'll discuss | ||
The query in Listing 2.23 will find a document whose ID is located in the `names/john` compare-exchange value. We'll discuss | ||
this feature again in Chapter 6. This feature relies on some of the low-level details of RavenDB distributed flow, and it | ||
will make more sense once we have gone over that. | ||
|
||
|
@@ -1551,7 +1551,7 @@ In order to aid in testing, RavenDB provides the `Raven.TestDriver` NuGet packag | |
instance of an `IDocumentStore` that talks to an in-memory database. Your tests will be very fast, they won't require you to do complex | ||
state setup before you start and they will be isolated from one another. | ||
|
||
Listing 2.23 shows the code for a simple test that saves and loads data from RavenDB. | ||
Listing 2.24 shows the code for a simple test that saves and loads data from RavenDB. | ||
|
||
```{caption="Basic CRUD test using RavenDB Test Driver" .cs} | ||
public class BasicCrud : RavenTestDriver<RavenExecLocator> | ||
|
@@ -1592,7 +1592,7 @@ public class BasicCrud : RavenTestDriver<RavenExecLocator> | |
} | ||
``` | ||
|
||
There are two interesting things happening in the code in Listing 2.20. The code inherits from the `RavenTestDriver<RavenExecLocator>` | ||
There are two interesting things happening in the code in Listing 2.21. The code inherits from the `RavenTestDriver<RavenExecLocator>` | ||
class, and it uses the `GetDocumentStore` method to get an instance of the document store. Let's break apart what's going on. | ||
|
||
The `RavenTestDriver<T>` class is the base test driver, which is responsible for setting up and tearing down databases. All | ||
|
@@ -1604,7 +1604,7 @@ behaves in the same manner as a typical RavenDB server. | |
|
||
If you've been paying attention, you might have noticed the difference between `RavenTestDriver<RavenExecLocator>` and | ||
`RavenTestDriver<T>`. What's that about? The `RavenTestDriver<T>` uses its generic argument to find the `Raven.Server.exe` | ||
executable. Listing 2.24 shows the implementation of `RavenExecLocator`. | ||
executable. Listing 2.25 shows the implementation of `RavenExecLocator`. | ||
|
||
```{caption="Letting the RavenTestDriver know where the Raven.Server exec is located"} | ||
public class RavenExecLocator : RavenTestDriver.Locator | ||
|
@@ -1614,7 +1614,7 @@ public class RavenExecLocator : RavenTestDriver.Locator | |
} | ||
``` | ||
|
||
The code in Listing 2.23 is using `xunit` for testing, but there's no dependency on the testing framework from | ||
The code in Listing 2.24 is using `xunit` for testing, but there's no dependency on the testing framework from | ||
`Raven.TestDriver`. You can use whatever testing framework you prefer. | ||
|
||
> **How does Raven.TestDriver work?** | ||
|
@@ -1635,7 +1635,7 @@ to inspect, validate and modify the content of the in-memory database (while the | |
you've looked at the database state, you can resume the test and continue execution. | ||
|
||
This makes it much easier to figure out what's going on because you can just _look_. Let's test this out. Add the following | ||
line between the two sessions in the code in Listing 2.20 and then run the test: | ||
line between the two sessions in the code in Listing 2.21 and then run the test: | ||
|
||
WaitForUserToContinueTheTest(store); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters